Comment puis-je en toute sécurité et extraire rapidement des chiffres à partir d'un int?

StackOverflow https://stackoverflow.com/questions/3605987

  •  25-09-2019
  •  | 
  •  

Question

Nous avons actuellement un code pour extraire les chiffres d'un int, mais je dois convertir en une plate-forme sans snprintf, et je suis peur d'un dépassement de mémoire tampon. J'ai commencé à écrire mon propre portable (et optimisé) snprintf mais on m'a dit de demander ici au cas où quelqu'un avait une meilleure idée.

int extract_op(int instruction)
{ 
    char buffer[OP_LEN+1];
    snprintf(buffer, sizeof(buffer), "%0*u", OP_LEN, instruction);
    return (buffer[1] - 48) * 10 + buffer[0] - 48;
}

Nous utilisons des chaînes C parce que la vitesse est très important.

Était-ce utile?

La solution

Utilisation sprintf doit être fine. sizeof type * 3 * CHAR_BIT / 8 + 2 est un tampon suffisamment grand pour l'impression d'un nombre entier de Type type. Vous pouvez simplifier cette expression si vous assumez CHAR_BIT est 8 ou si vous ne vous préoccupez formats non signés. L'idée de base est que chaque octet contribue au plus 3 chiffres en décimal (ou octal), et vous avez besoin d'espace pour un signe et la terminaison nulle.

Autres conseils

Vous n'avez pas besoin de former instruction dans un tableau de caractères à cet effet; vous avez juste besoin de garder « les deux chiffres supérieurs », comme suit:

int extract_op(unsigned int instruction)
{
    int first = 0;
    int second = 0;
    while(instruction) {
        second = first;
        first = instruction % 10;
        instruction /= 10;
    }
    return first + 10 * second;
}

Je pense que l'expression dans le return est faux, mais il ne reproduit ce que vous faites. Dix fois le secondes chiffres, ainsi que le premier

Je soupçonne que la vitesse pourrait être encore mieux que ce que vous obtenez maintenant, mais c'est à vous mesurer sur votre plate-forme spécifique et compilateur, bien sûr.

Jusqu'à présent, il y a une réponse qui permute les deux derniers chiffres et qui permute les deux premiers ... il me semble que "%0*u", OP_LEN est de forcer la sortie à une largeur particulière, et l'importance des chiffres extraits est prédéterminée par OP_LEN.

En supposant OP_LEN est une macro, nous pouvons obtenir 10 ^ (OP_LEN-2) avec

#define DIVISOR ( (int) ( 1.e ## OP_LEN * 0.01 ) )

Alors, semblable à la réponse de @ zneak,

int extract_op( int instruction )
{
    instruction /= DIVISOR;
    int tens = (instruction / 10) % 10;
    int units = instruction % 10;
    return units * 10 + tens;
}

#undef DIVISOR

U peut stocker le chiffre u obtiennent en réseau. Celui-ci était CODE EXPLIQUE PAR ALEX. Ici, je suis d'ajouter certaines variables.

int a[5];

int extract_op(unsigned int instruction)
{
int i=0;    
int first = 0;
    int second = 0;
    while(instruction) {
        second = first;
        first = instruction % 10;
        instruction /= 10;
    }
    a[i]=first;
}

Ceci est quelque chose fonctionnera pour tous les entiers auront max 5 chiffres. Mais encore, si tu veux prendre un tableau dynamique alors u peut utiliser la liste de liens

devrait fonctionner aussi pour 0 et <0.

int extract_op( int instruction )
{
  int numd = 1;
  while( instruction /= 10 )
    ++numd;
  return numd;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top