2 votes

Transfert buggué de nombres longs simples vers un tableau d'int.

J'essaie de saisir un tableau Long Long Int et de répartir chaque numéro de place dans son propre emplacement dans un tableau, dans l'ordre bien sûr, avec array[0] étant le plus grand nombre.

Ainsi, par exemple, si le nombre est 314, alors le tableau [0] = 3, le tableau [1] = 1, et le tableau [2] = 4.

Ceci fait partie d'un projet de calculatrice pour un microcontrôleur où j'écris la bibliothèque graphique (pour le plaisir) et utilise des tableaux pour afficher chaque ligne.

Le problème est qu'il doit être capable de traiter des nombres très élevés (9 999 999 999+), et j'ai des problèmes avec les grands nombres. Si la longueur est inférieure à 1 000 000, il écrit tous les nombres parfaitement, mais plus j'ajoute de nombres, plus ils commencent à être mal écrits vers la fin.

Par exemple, 1 234 567 890 s'affiche comme 1 234 567 966.

Voici le bout de code que j'utilise :

long long int number = 1234567890;
int answerArray[10];
int numberLength = 10;

for(writeNumber = 0; writeNumber < numberLength; writeNumber++)
{
    answerArray[writeNumber] = ((int)(number / pow(10, (numberLength - 1 - writeNumber))) % 10;
}

Je suis presque sûr que cela a à voir avec le "%" et les types de données multiples, car n'importe quel nombre dans la plage Int fonctionne parfaitement.

Tu vois où je vais mal ? Y a-t-il une meilleure façon d'atteindre mon objectif ? Des conseils pour les grands nombres ?

3voto

Philipp Claßen Points 4863

La signature de pow es

double pow(double x, double y);

Lorsque vous appelez la fonction, le calcul utilisera implicitement la virgule flottante. C'est pourquoi il n'est plus exact comme les opérations sur les entiers purs.

De plus, vous devez faire attention à la façon dont vous lancez les images int .

Dans votre question, vous avez

((int)(number / pow(10, (numberLength - 1 - writeNumber))) % 10;

Les parenthèses ne correspondent pas, donc je suppose que tu voulais dire.. :

(int)(number / pow(10, (numberLength - 1 - writeNumber))) % 10;

Cependant, ici vous lancez un nombre qui peut dépasser l'intervalle de int avant d'appliquer l'opération modulo 10. Cela peut entraîner un débordement d'entier. Le code fait la même chose que si vous aviez écrit :

((int)(number / pow(10, (numberLength - 1 - writeNumber)))) % 10;

Pour éviter le débordement, il serait préférable d'effectuer l'opération modulo en premier. Cependant, vous traitez implicitement avec un double à ce stade (à cause de pow), ce qui n'est pas idéal non plus. Il est préférable de s'en tenir aux opérations sur les entiers purs pour éviter ces écueils.

2voto

Daniel Walker Points 3519

Votre problème est que vous mettez ce qui est potentiellement un très grand nombre dans un int . Regardez l'itération lorsque writeNumber es numberLength-1 . Dans ce cas, vous divisez un long long par 1, puis en forçant le résultat dans un fichier int . Une fois que number devient plus grand que 2^31-1, vous allez rencontrer des problèmes.

Vous devriez supprimer complètement le casting ainsi que l'appel à pow . Au lieu de cela, vous devez itérativement saisir le chiffre suivant en le modulant par 10 puis en divisant number (ou une copie de celui-ci) par 10.

Par exemple,

int index = sizeof(answerArray)/sizeof(answerArray[0]);
for (long long x=number; x>0; x /= 10) {
    answerArray[--index] = x%10;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X