2017-07-19 7 views
0

Das Zuweisen eines doppelten Werts, der in Variable A gespeichert wird, zu einer Variablen B ändert seinen Wert, sobald der Wert unter 0,000001 fällt. Ich habe über Probleme mit 80-Bit-FPUs gelesen, aber in diesem Fall sollte dieses Problem nicht auftreten, da ich nur einen Wert zuweise, ohne etwas damit zu berechnen. Hier einige Stück Beispielcode:Doppelte Zuweisung ändert Wert

double elapsed = _sinceCreation.elapsed(); 
if (benchmark->minTime > elapsed) { 
    benchmark->minTime = elapsed; 
} 

benchmark->minTime_sinceCreation.elapsed() sollte gleich, aber es funktioniert nicht überraschend! Was könnte der Grund dafür sein? Und wie kann ich dieses Verhalten beheben?

EDIT:

meine Erklärung abzuschließen, hier ist das Verfahren, bei dem es seltsam (inklusive Testausgang Gleichheit zu überprüfen) verhält:

double elapsed = _sinceCreation.elapsed(); 

if (_benchmarkMap.find(benchmark->methodName) == _benchmarkMap.end()) { 
    _benchmarkMap[benchmark->methodName] = benchmark; 
} 

if (benchmark->times.size() >= _benchmarkLimitPerMethod || 
    benchmark->times.size() >= benchmark->times.max_size()) { 
    benchmark->times.pop_front(); 
    benchmark->maxSizeReached = true; 
} 

benchmark->times.push_back(elapsed); 

if (benchmark->minTime > elapsed) { 
    std::cout << printToString("before min time: {0:0.15f} elapsed: {0:0.15f}", benchmark->minTime, elapsed) << std::endl; 
    benchmark->minTime = elapsed; 
    std::cout << printToString("after min time: {0:0.15f} elapsed: {0:0.15f}", benchmark->minTime, elapsed) << std::endl; 
} 

if (benchmark->maxTime < elapsed) 
    benchmark->maxTime = elapsed; 

_sinceCreation ist eine Zeitstempel-Klasse, Rückkehr Doppel Sekunden seit letzten setCurrentTime() und printToString() ist ein eigener Wrapper für fmtlib.

+1

Bitte geben Sie eine [mcve] –

+0

Sie hat nicht gezeigt, wie Sie festgestellt haben, dass die Werte nicht gleich sind. – PaulMcKenzie

+0

https://stackoverflow.com/questions/17333/what-is-the-most-effective-way-for-float-and-double-comparison –

Antwort

0

Es geht um Präzision. Es gibt eine begrenzte Genauigkeit auch für das Doppelte. Wenn Sie darüber hinausgehen, ist der Wert beschädigt. Es spielt keine Rolle, ob Sie etwas berechnen oder nicht, die Zuweisung eines Wertes ist immer noch eine Operation, der Wert geht durch das Prozessorregister, und weil zu "groß" ist abgeschnitten

+0

Also sollte ich stattdessen ein 'long double' verwenden, um die Präzision zu erhöhen? – Migsi

+0

Sie könnten versuchen, aber seien Sie sich bewusst, es gibt immer ein Limit –

+0

Ich würde auch hinzufügen, dass einige Zahlen, die einfach in Dezimal darzustellen scheinen schwer in binär sind. Zum Beispiel scheint .1 einfach in Dezimal darzustellen. Es ist die Grundeinheit, während du im Binärformat mit .5, .25, .125 ... bis zum Überdruss von Bits arbeitest. Darstellung von .1 wird als 00111101110011001100110011001101 im IEEE-Format dargestellt. Dieser Wert entspricht 0,100000001490116119384765625, nicht genau 0,1. Siehe: https://www.h-schmidt.net/FloatConverter/IEEE754.html – Erich