Проблема.
Компилятор Microsoft Visual С++ 2005, 32-битные окна xp sp3, amd 64 x2 cpu.
код:
double a = 3015.0;
double b = 0.00025298219406977296;
//*((unsigned __int64*)(&a)) == 0x40a78e0000000000
//*((unsigned __int64*)(&b)) == 0x3f30945640000000
double f = a/b;//3015/0.00025298219406977296;
результат вычисления (т.е. "f" ) равен 11917835.000000000 (((unsigned __int64) (& f)) == 0x4166bb4160000000), хотя это должно быть 11917834.814763514 (т.е. ((без знака __int64) (& f)) = = 0x4166bb415a128aef).
То есть дробная часть теряется.
К сожалению, мне нужна дробная часть, чтобы быть правильной.
Вопросы:
1) Почему это происходит?
2) Как я могу исправить проблему?
Дополнительная информация:
0) Результат берется непосредственно из окна "watch" (он не был напечатан, и я не забыл установить точность печати). Я также предоставил шестнадцатеричный дамп переменной с плавающей запятой, поэтому я абсолютно уверен в результате вычисления.
1) Разборка f = a/b:
fld qword ptr [a]
fdiv qword ptr [b]
fstp qword ptr [f]
2) f = 3015/0,00025298219406977296; дает правильный результат (f == 11917834.814763514, ((unsigned __int64) (& f)) == 0x4166bb415a128aef), но похоже, что в этом случае результат просто вычисляется во время компиляции:
fld qword ptr [[email protected] (828EA0h)]
fstp qword ptr [f]
Итак, как я могу исправить эту проблему?
P.S. Я нашел временное обходное решение (мне нужна только дробная часть деления, поэтому я просто использую f = fmod (a/b)/b на данный момент), но мне все же хотелось бы знать, как правильно исправить эту проблему - double точность должна быть 16 десятичных цифр, поэтому такой расчет не должен вызывать проблем.