2017-03-23 2 views
-4

S'il vous plaît expliquer pourquoi pow() ne fonctionne pas pour le grand nombre tel que 2^63? (Si vous écrivez une fonction pow avec le prototype de pow(long long int a, long long int b) au lieu de pow(double a, double b) il fonctionne très bien.)Fonction pow() ne fonctionne pas correctement lors de l'utilisation de grands nombres?

est le code ici :

#include <stdio.h> 
#include <math.h> 
int main() 
{ 
    printf("%.0lf\n" ,pow((double)2,63)); 
} 

sortie:

9223372036854775800 

vraie réponse:

9223372036854775808 

merci.

+0

Veuillez inclure un [mcve] dans votre question. –

+3

Définir "ne fonctionne pas correctement", idéalement avec la sortie REAL – fvu

+0

Savez-vous ce que différents types signifient? –

Répondre

0

pow fonctionne très bien. MSVC printf est bogué et tronque la sortie pour le virgule flottante.

+0

Pourquoi la downvote? '9223372036854775800' n'est pas une valeur possible qui peut être représentée dans un' double', donc ce n'est évidemment pas ce que 'pow' a renvoyé. La seule façon dont il aurait pu apparaître est que 'printf' imprime mal, et la seule implémentation que je connaisse avec ce bug est MSVC. –

+0

@ R..Je ne vous donne pas downvote !! –

+0

@FatemehKarimi Je n'ai pas downvote non plus mais vous pourriez être plus utile que cela en mettant à jour quel compilateur/bibliothèque vous utilisez (MSVC ou non, si c'est le cas, la version que vous utilisez) et comment vous compilez, etc. –

4

printf("%.0lf\n", x); n'est pas nécessaire pour imprimer le exacte la valeur de (double) x.

Un compilateur C conforme/bibliothèque C standard génèrera du code qui imprimera environ DBL_DECIMAL_DIG (généralement 17), corrigera significativement chiffres décimaux. D'autres peuvent imprimer plus de chiffres correctement. (Mine imprimé 9223372036854775808). Voir <float.h>

// 456789
9223372036854775800 // answer 
9223372036854775808 // true answer: 

exemple extrême

DBL_MAX peuvent avoir les exact value de

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368 

Pourtant, de nombreux résultats de printf("%.0lf\n" ,DBL_MAX); rapportera des zéros après un certain point

179769313486231570814527423731704356798070600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 

OP later added que la fonction de référence pow() était long long int pow(long long int a, long long int b). pow_ll_version(2,63) devrait entraîner 9223372036854775808, ce qui est passé 1 beaucoup de LLONG_MAX - certainement un comportement indéfini. Supposons qu'il enveloppé à -9223372036854775808, et a été imprimé avec printf("%llu\n" , long_long_int_result); (plus de UB comme spécificateur et type mis-apparié). Cela peut avoir donné 9223372036854775808 à OP.

printf() La sortie des entiers est exacte, contrairement aux valeurs à virgule flottante.

+1

Le ** compilateur ** n'imprimera rien. C'est l'implémentation de la bibliothèque standard, c'est-à-dire l'environnement. – Olaf