2016-04-13 2 views
1

Wir wissen, dass double s Genauigkeit ihres Wertes verlieren, wenn Sie die Anzahl der Dezimalpunkte erhöhen. Aber wenn ich denselben Wert double zweimal auf der gleichen Maschine verwende, werde ich garantiert haben, um die gleiche Ungenauigkeit zu haben? Zum Beispiel:Ist die Ungenauigkeit eines doppelten Werts auf der gleichen Maschine garantiert konsistent?

double d1 = 123.456;//actually becomes 123.45600001 
double d2 = 123.456;//is guaranteed to become 123.45600001? 

Der Einfachheit halber lassen Sie nur mit C++ bleiben.

+3

Die meisten C++ - Implementierungen entsprechen dem IEEE-Gleitkommastandard. Also ja. – callyalater

+2

@callyalater, nein, tut es nicht. – SergeyA

+2

@SergeyA Sie haben Recht. Ich wollte sagen [die meisten Implementierungen sind] (https://en.wikipedia.org/wiki/Double-precision_floating-point_format#C_and_C.2B.2B). – callyalater

Antwort

2

Nein, Sie haben keine Garantie. C++ - Implementierungen sind nicht an den IEEE-Standard gebunden und können beliebige binäre Repräsentationen auswählen.

Während es unwahrscheinlich ist, dass sie nur ihre eigenen erfinden, schwanken sie normalerweise (sogar innerhalb des gleichen Anbieters) darin, wie sie die "nicht darstellbaren" Zahlen darstellen - sie können mit einer größeren Zahl oder einer kleineren Zahl dargestellt werden - und dies Darstellungsänderungen (ich glaube, sogar verschiedene floating math Optionen für gleichen gcc können dies beeinflussen).

+0

Ich bin mir ziemlich sicher, dass "d1" im Beispiel des OP gleich "d2" sein muss. Ich glaube nicht, dass Sie eine Implementierung haben könnten, die dasselbe Literal in zwei verschiedene Werte konvertiert. Es stimmt zwar, dass "123.456" nicht gleich "123 + .456" – NathanOliver

+1

@NathanOliver sein muss, ich habe die Frage nicht wörtlich genommen und dachte, dass diese Gleichungen nur zur Veranschaulichung dienen. Es ist jedoch nicht schwer, sich eine Implementierung vorzustellen, bei der diese beiden Variablen nicht gleichberechtigt sind - stellen Sie sich einen FPU-Chip vor, der abhängig vom Zufallswert auf- oder abrundet - um die Verzerrung zu reduzieren/ – SergeyA

+0

Zufälliges Runden ist kein zulässiges IEEE 754 Rundungsmodi. Diese sind: 1. Runde zum nächsten, Verbindungen zur geraden, 2.Runde zum nächsten, Bindungen weg von Null, 3. Runde in Richtung Null, 4. Runde in Richtung + ∞, 5. Runde in Richtung -∞ In allen diesen Modi wird die Rundung angewendet, wenn zwei Werte gleich weit von der gegebener Wert. In keinem Fall sollte ein Compiler eine Repräsentation wählen, die weiter von der gegebenen Dezimalkonstante entfernt ist als ein anderer gesetzlicher Wert. –

2

In Ihrem Fall d1 == d2 werden true zurückkehren, und es wird fast immer true zurück auf jede richtig Compiler/Architektur arbeitet. Selbst wenn der Compiler/die Architektur nicht IEEE-konform sind, ist es extrem unwahrscheinlich, dass die Bereitstellung eines identischen Symbols für 123.456 unterschiedliche Werte bei mehreren Aufrufen zurückgibt.

Aber, wenn Sie den folgenden Code hatte:

double d1 = 123.456; 
double d2 = get_123_456_from_network_service(service); 

Diese Garantie würde aufhören zu sein. 123.456 wird immer die gleiche auf Ihrem Computer sein, aber wenn ein anderer Computer versucht, das gleiche Symbol zu verwenden, und nicht IEEE-konform ist (oder wenn deins nicht ist), dann besteht eine gute Chance, dass die Werte unterschiedlich wären .

0

Wenn Ihr Compiler dem Standard IEEE 754 (IEC 559) entspricht, sollten sie identisch sein. Sie können überprüfen, ob es IEEE-kompatibel mit std::numeric_limits<T>::is_iec559 ist. Die meisten Implementierungen sind IEEE-konform, dies ist jedoch keine Garantie.

Verwandte Themen