calcul inexact causé par un type de données inexact utiliser

#include #include int main(){ int num,onum,numl=0,tem,nnum=0; printf("Enter num: "); scanf("%d", &num); onum =num; while (num!=0){ num = num/10; ++numl; } num = onum; while (num!=0){ tem = num%10; nnum += pow(tem,numl); printf("%d",nnum); num /= 10 ; } if (nnum == onum){ printf("is"); } else{ printf("not"); } } 

fonctionne bien avec d’autres nombres narcissiques.

mais quand l’entrée 153, 5 ** 3 est comptée à 124, pourquoi? entrez la description de l'image ici


Cette question est la duplication de nombreuses questions . Et la réponse ci-dessous est la réponse la plus facile à comprendre.

En une phrase, le calcul inexact est causé par {inexact {utilisation de type de données} ou {compilateur} ou {FPU}}.

J’ai évité l’erreur en mettant à jour mon compilateur vers gcc 7.2. Mais résoudre le problème nécessite une fonction pow pour integer.

pow (dans pow(tem,numl) ) est une fonction à virgule flottante. Cela signifie qu’il renvoie un double , lié à une imprécision de virgule flottante et à un arrondi (si pow renvoie 124.999999 cela n’a aucun impact sur le calcul en virgule flottante, mais il le fait lorsqu’il est affecté à un entier en raison d’une troncature)

Donc, s’appuyer sur la valeur de retour de pow peut fonctionner ou non (dépend des valeurs, du FPU, des bibliothèques mathématiques du compilateur). Et le fait que “parfois, il émette une valeur légèrement inférieure” est un cadeau pour ce problème d’inexactitude en virgule flottante.

Puisque vous travaillez exclusivement avec des nombres entiers, j’utiliserais plutôt l’exponentiation des nombres entiers, soit avec une boucle simple, soit avec des algorithmes plus complexes ( Le moyen le plus efficace d’implémenter une fonction de puissance basée sur un nombre entier pow (int, int) )