проблема.
Компилятор Microsoft Visual C ++ 2005, 32-разрядная версия Windows XP SP3, 64-разрядный процессор amd.
Код:
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 ( ((без знака __int64 ) (& f)) == 0x4166bb4160000000), хотя он должен быть 11917834.814763514 (т. Е. ((без знака __int64 *) 1011 *) (& f)) == 0x4166bb415a128aef).
То есть дробная часть теряется.
К сожалению, мне нужна дробная часть, чтобы быть правильной.
Вопросы:
1) Почему это происходит?
2) Как я могу решить проблему?
Дополнительная информация:
0) Результат берется напрямую из окна «Смотреть» (оно не было напечатано, и я не забыл установить точность печати). Я также предоставил шестнадцатеричный дамп переменной с плавающей точкой, так что я абсолютно уверен в результате вычисления.
1) Разборка f = a / b:
fld qword ptr [a]
fdiv qword ptr [b]
fstp qword ptr [f]
2) f = 3015 / 0,00025298219406977296; дает правильный результат (f == 11917834.814763514, ((без знака __int64 ) (& f)) == 0x4166bb415a128aef), но в этом случае результат просто вычисляется во время компиляции:
fld qword ptr [__real@4166bb415a128aef (828EA0h)]
fstp qword ptr [f]
Итак, как я могу решить эту проблему?
P.S. Я нашел временный обходной путь (мне нужна только дробная часть деления, поэтому я сейчас просто использую f = fmod (a / b) / b), но я все еще хотел бы знать, как правильно решить эту проблему - дважды точность должна быть 16 десятичных цифр, поэтому такие вычисления не должны вызывать проблем.