Frage

Ich habe das nur aus Spaß gemacht (also nicht gerade eine Frage, ich kann sehen, dass das Downmodding bereits stattfindet), aber anstelle von Googles Neufund Unfähigkeit machen Mathematik korrekt (prüfen Sie!laut Google 500.000.000.000.002 - 500.000.000.000.001 = 0), dachte ich mir, ich würde Folgendes in C versuchen, um ein wenig Theorie zu betreiben.

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);
}

Wenn Sie dieses Programm ausführen, erhalten Sie Folgendes

   399999999999999 - 399999999999998 = 0.000000
   500000000000002 - 500000000000001 = 0.000000

Es scheint, als würde Google eine einfache 32-Bit-Floating-Genauigkeit verwenden (der Fehler hier). Wenn Sie im obigen Code Float durch Double ersetzen, beheben Sie das Problem!Könnte es das sein?

/mp

War es hilfreich?

Lösung

Versuchen Sie in C# (double.maxvalue == (double.maxvalue - 100)) , Sie erhalten true ...

aber so soll es sein:

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

Wenn Sie darüber nachdenken, haben Sie 64 Bit, die eine Zahl größer als 2 ^ 64 (double.maxvalue) darstellen, daher ist mit Ungenauigkeiten zu rechnen.

Andere Tipps

Weitere Informationen zu dieser Art von Albernheit finden Sie in diesem schönen Artikel zum Windows-Rechner.

Wenn man die Innenseiten wechselt, merkt es niemand

Die Innereien von CALC - der arithmetische Motor - wurden vollständig weggeworfen und von Grund auf neu geschrieben.Die Standard IEEE Gleitkomma-Bibliothek wurde durch eine Arithmetik mit beliebiger Genauigkeit Bibliothek.Das wurde nach Menschen gemacht. hielt das Schreiben ha-ha Artikel darüber, wie Calc konnte keine Dezimalarithmetik ausführen richtig, dass z.B. Computing 10,21 - 10,2 ergeben 0,01000000000016.

Es scheint, als würde Google eine einfache 32-Bit-Floating-Genauigkeit verwenden (der Fehler hier). Wenn Sie im obigen Code Float durch Double ersetzen, beheben Sie das Problem!Könnte es das sein?

Nein, Sie verschieben das Problem einfach.Bei Doubles tritt immer noch das gleiche Problem auf, nur bei größeren Zahlen.

@ebel

Wenn Sie darüber nachdenken, haben Sie 64 Bit, die eine Zahl größer als 2 ^ 64 (double.maxvalue) darstellen, daher ist mit Ungenauigkeiten zu rechnen.

2^64 ist nicht der Maximalwert eines Doubles.2^64 ist die Anzahl der eindeutigen Werte, die ein Double (oder ein anderer 64-Bit-Typ) enthalten kann. Double.MaxValue ist gleich 1,79769313486232e308.

Eine Ungenauigkeit bei Gleitkommazahlen entsteht nicht durch die Darstellung von Werten größer als Double.MaxValue (was unmöglich ist, ausgenommen Double.PositiveInfinity).Dies liegt daran, dass der gewünschte Wertebereich einfach zu groß ist, um in den Datentyp zu passen.Deshalb verzichten wir auf Präzision im Austausch für eine größere effektive Reichweite.Im Wesentlichen lassen wir signifikante Ziffern fallen, um dafür einen größeren Exponentenbereich zu erhalten.

@DrPizza

Nicht mal;Die IEEE-Kodierungen verwenden mehrere Kodierungen für dieselben Werte.Konkret wird NaN durch einen Exponenten aller Bits-1 und dann durch einen beliebigen Wert ungleich Null für die Mantisse dargestellt.Somit gibt es 252 NaNs für Doppel und 223 NaNs für Einzel.

WAHR.Ich habe doppelte Kodierungen nicht berücksichtigt.Es sind tatsächlich 252-1 NaNs für Doppel und 223Allerdings -1 NaNs für Singles.:P

2^64 ist nicht der Maximalwert eines Doubles.2^64 ist die Anzahl der eindeutigen Werte, die ein Double (oder ein anderer 64-Bit-Typ) enthalten kann.Double.MaxValue ist gleich 1,79769313486232e308.

Nicht mal;Die IEEE-Kodierungen verwenden mehrere Kodierungen für dieselben Werte.Insbesondere wird NaN durch einen Exponenten aller Bits-1 und dann dargestellt beliebig Wert ungleich Null für die Mantisse.Somit gibt es 252 NaNs für Doppel, 223 NaNs für Singles.

WAHR.Ich habe doppelte Kodierungen nicht berücksichtigt.Allerdings gibt es tatsächlich 252-1 NaNs für Doppel und 223-1 NaNs für Einzel.:P

Doh, ich habe vergessen, die Unendlichkeiten zu subtrahieren.

Die grob geschätzte Version dieses Problems, die ich gelernt habe, ist, dass 32-Bit-Floats eine Genauigkeit von 5 Stellen und 64-Bit-Floats eine Genauigkeit von 15 Stellen bieten.Dies hängt natürlich davon ab, wie die Floats codiert sind, aber es ist ein ziemlich guter Ausgangspunkt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top