c ++ Gleitkomma-Präzisionsverlust: 3015 / 0.00025298219406977296

Das Problem.

Microsoft Visual C ++ 2005-Compiler, 32-Bit-Windows XP SP3 und 64 x 2-CPU.

Code:

double a = 3015.0; 
double b = 0.00025298219406977296;
//*((unsigned __int64*)(&a)) == 0x40a78e0000000000  
//*((unsigned __int64*)(&b)) == 0x3f30945640000000  
double f = a/b;//3015/0.00025298219406977296;

das Ergebnis der Berechnung (d. h. "f") ist 11917835.000000000 (((nicht signiert __int64) (& f)) == 0x4166bb4160000000) obwohl es 11917834.814763514 (d. h.((nicht signiert __int64) (& f)) == 0x4166bb415a128aef).
Das heißt Bruchteil ist verloren.
Leider brauche ich einen Bruchteil, um korrekt zu sein.

Fragen:
1) Warum passiert das?
2) Wie kann ich das Problem beheben?

Zusätzliche Information:
0) Das Ergebnis wird genommendirekt aus dem "watch" -Fenster (es wurde nicht gedruckt, und ich habe nicht vergessen, die Druckgenauigkeit einzustellen). Ich habe auch einen hexadezimalen Speicherauszug der Fließkommavariablen bereitgestellt, daher bin ich mir über das Berechnungsergebnis absolut sicher.
1) Die Demontage von f = a / b ist:

fld         qword ptr [a]  
fdiv        qword ptr [b]  
fstp        qword ptr [f]  

2) f = 3015 / 0,00025298219406977296; liefert korrektes Ergebnis (f == 11917834.814763514,((nicht signiert __int64) (& f)) == 0x4166bb415a128aef), aber in diesem Fall wird das Ergebnis einfach während der Kompilierungszeit berechnet:

fld         qword ptr [__real@4166bb415a128aef (828EA0h)]  
fstp        qword ptr [f]  

Wie kann ich dieses Problem beheben?

P.S. Ich habe eine vorübergehende Problemumgehung gefunden (ich benötige nur einen Bruchteil der Division, daher verwende ich im Moment einfach f = fmod (a / b) / b), möchte aber trotzdem wissen, wie dieses Problem richtig behoben werden kann - double Die Genauigkeit sollte 16 Dezimalstellen betragen, daher sollte eine solche Berechnung keine Probleme verursachen.

Antworten auf die Frage(5)

Ihre Antwort auf die Frage