2016-08-23 4 views
0

eine Frage, die ich gesehen und nicht ganz verstanden habe.Multiplikation von Doppelvariablen

zuerst erstellen wir beliebige Werte:

int x = random(); 
int y = random(); 
int z = random(); 

(int 32 Bit) dann weiter mit:

double dx = (double) x; 
double dy = (double) y; 
double dz = (double) z; 

(Doppel 64 Bits)

die Frage sagen sollte wenn die nächsten Anweisungen sind immer wahr (gibt 1 zurück) oder nicht.

a. dx+dy+dz==dz+dy+dx 

b. dx*dy*dz==dz*dy*dx 

die Antwort auf (a) war: „Ja, Innerhalb der Reichweite der exakten Darstellung von Doppel des“ (so ist es oder ist es nicht immer wahr? Und wenn es nicht immer wahr ist, Ich möchte ein Beispiel von 3 Werten für dx, dy, dz, die 0)

die Antwort zu (b) war "nein, zB dx = Tmax, dy = Tmax-1, dz = Tmax-2" Ich versuchte es und es stellte sich heraus, dass es das gleiche Ergebnis war (aber wahrscheinlich lag ich falsch: - /)

Ich würde gerne verstehen, warum diese Antworten richtig sind

danke!

Antwort

1

In Fließkomma-Arithmetik sollten Sie nie auf Gleichheit prüfen. Ein klassisches Beispiel ist 0.1 + 0.2 != 0.3. (Siehe auch http://0.30000000000000004.com/ für weitere Informationen, insbesondere um zu sehen, ob Ihre Sprache das vor Ihnen verbirgt. Es hat eine schöne Erklärung, wie dies entsteht, weil 0,1 und 0,3 im Doppel nicht genau dargestellt werden können.) Fließkommawerte sollten stattdessen überprüft werden Sehen Sie, ob sie in einem bestimmten Bereich nahe genug beieinander sind, normalerweise "Toleranz" genannt.

Siehe IEEE 754 Definition: https://en.wikipedia.org/wiki/Double-precision_floating-point_format

ich mit der Antwort nicht einverstanden ist, um (a), denn es ist sinnlos, zu spezifizieren, was durch einen Doppel „genau dargestellt“ werden kann - wenn jede Eingabe die doppelte Darstellung der ist gegeben zufällige Bits (x, y, z), dann ist es per Definition die genaue Darstellung. Plus, es ist zweifelhaft zu sagen "Ja, aber nur unter bestimmten Bedingungen" als Antwort auf "ist das immer wahr?" Die Antwort lautet in diesem Fall "Nein".

Ein Gegenbeispiel zu (a) ist unten. Ich konstruierte dies, indem ich bedenke, dass Fließkommazahlen nur eine gewisse relative Genauigkeit haben, so dass das Hinzufügen einer sehr kleinen Zahl zu einer sehr großen keinen Unterschied machen kann. Machen Sie diese kleine Zahl groß genug, und es wird.

  • 1e16 + 1 + 1 = 10000000000000000
  • 1 + 1 + 1e16 = 10000000000000002

Wie für (b), das erste, was ich zufällig versucht, war ein Gegenbeispiel:

  • 0.1 * 0.1 * 0.7 = 0.007000000000000001
  • 0.7 * 0.1 * 0.1 = 0.006999999999999999