2008-08-25 4 views
4

Je l'ai fait juste pour le plaisir (donc pas exactement une question, je peux voir le downmodding se passe déjà) mais, en lieu et place de toute nouvelle de Google inability faire mathcorrectly (vérifier selon Google 500.000.000.000.002 - 500,000,000,000,001 = 0), J'ai pensé que j'essaierais ce qui suit en C pour faire un peu de théorie.Le calculateur Google Glitch, pourrait flotter contre le double être une raison possible?

int main() 
{ 
    char* a = "399999999999999"; 
    char* b = "399999999999998"; 

    float da = atof(a); 
    float db = atof(b); 

    printf("%s - %s = %f\n", a, b, da-db); 

    a = "500000000000002"; 
    b = "500000000000001"; 
    da = atof(a); 
    db = atof(b); 
    printf("%s - %s = %f\n", a, b, da-db); 
} 

Lorsque vous exécutez ce programme, vous obtenez les éléments suivants

399999999999999 - 399999999999998 = 0.000000 
    500000000000002 - 500000000000001 = 0.000000 

Il semblerait que Google utilise simplement une précision flottante 32 bits (l'erreur ici), si vous changez de flotteur pour double dans la ci-dessus, vous corrigez le problème! Cela pourrait-il être cela?

/mp

Répondre

2

en C#, essayez (double.maxvalue == (double.maxvalue - 100)), vous obtiendrez vrai ...

mais c'est ce qu'il est censé être:

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

en pensant à ce sujet, vous avez 64 bits représentant un nombre supérieur à 2^64 (double.maxvalue), donc l'inexactitude est attendue.

4

Pour plus de ce genre de niaiserie voir ce bel article se rapportant à la calculatrice de Windows.

When you change the insides, nobody notices

Les entrailles de Calc - le moteur arithmétique - a été complètement jetés et réécrites à partir de zéro. La bibliothèque standard à virgule flottante IEEE a été remplacée par une bibliothèque arithmétique arbitraire de précision . Cela a été fait après que les gens ont continué à écrire des articles ha-ha sur la façon dont Calc ne pouvait pas faire l'arithmétique décimale correctement, que par exemple calculer 10.21 - 10.2 a abouti à 0.0100000000000016.

2

Il semblerait que Google utilise simplement une précision flottante 32 bits (l'erreur ici), si vous changez de flotteur pour double dans le code ci-dessus, vous résoudre le problème! Cela pourrait-il être cela?

Non, il vous suffit de reporter le problème. les doubles présentent toujours le même problème, juste avec des nombres plus grands.

1

@ebel

y penser, vous avez 64 bits représentant un nombre supérieur à 2^64 (double.maxvalue), si l'inexactitude est attendue.

2^64 n'est pas la valeur maximale d'un double. 2^64 est le nombre de valeurs uniques qu'un double (ou tout autre type 64 bits) peut contenir. Double.MaxValue est incroyablement similaire à 1.79769313486232e308.

L'inexactitude avec des nombres à virgule flottante ne provient pas de la représentation de valeurs supérieures à Double.MaxValue (ce qui est impossible, à l'exclusion de Double.PositiveInfinity). Cela vient du fait que la plage de valeurs désirée est simplement trop grande pour tenir dans le type de données. Nous abandonnons donc la précision en échange d'une gamme efficace plus large. En substance, nous laissons tomber des chiffres significatifs en échange d'une plus grande gamme d'exposants.

@DrPizza

Pas même; les codages IEEE utilisent plusieurs codages pour les mêmes valeurs. Plus précisément, NaN est représenté par un exposant de tout-bits-1, puis toute valeur non nulle pour la mantisse. En tant que tel, il y a 252 NaN pour les doubles, 223 NaN pour les célibataires.

True. Je n'ai pas tenu compte des codages en double. Il y a en fait 2 -1 NaNs pour les doubles et 2 -1 NaNs pour les célibataires, cependant. : p

0

2^64 n'est pas la valeur maximale d'un double. 2^64 est le nombre de valeurs uniques qu'un double (ou tout autre type 64 bits) peut contenir. Double.MaxValue est égal à 1.79769313486232e308.

Pas pair; les codages IEEE utilisent plusieurs codages pour les mêmes valeurs. Plus précisément, NaN est représenté par un exposant de tout-bits-1, puis toute valeur non nulle pour la mantisse. À ce titre, il y a 2 NaNs pour les doubles, 2 NaNs pour les célibataires.

0

True. Je n'ai pas tenu compte des codages en double. Il y a en fait 252-1 NaNs pour les doubles et 223-1 NaN pour les simples. : p

Doh, j'ai oublié de soustraire les infinis.

0

La version d'estimation approximative de ce numéro que j'ai apprise est que les flottants de 32 bits vous donnent 5 chiffres de précision et les flottants de 64 bits vous donnent 15 chiffres de précision. Cela va bien sûr varier en fonction de la façon dont les flotteurs sont encodés, mais c'est un très bon point de départ.

Questions connexes