Проблема.C++ с плавающей запятой точность: 3015/0.00025298219406977296
Компилятор Microsoft Visual C++ 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;
результат вычисления (т.е. "е") является 11917835,000000000 (((неподписанных __int64) (& е)) == 0x4166bb4160000000), хотя это должно быть 11917834,814763514 (т.е. ((без знака __int64) (& f)) == 0x4166bb415a128aef).
I.e. дробная часть теряется.
К сожалению, мне нужна дробная часть, чтобы быть правильной.
Вопросы:
1) Почему это происходит?
2) Как я могу исправить проблему?
Дополнительная информация:
0) Результат берется непосредственно от «смотреть» окна (это не было напечатано, и я не забыл установить точность печати). Я также предоставил шестнадцатеричный дамп переменной с плавающей точкой, поэтому я абсолютно уверен в результате вычисления.
1) Разборка F = А/В:
fld qword ptr [a]
fdiv qword ptr [b]
fstp qword ptr [f]
2) F = 3015/0,00025298219406977296; дает правильный результат (е == 11917834.814763514, ((неподписанных __int64) (& ж)) == 0x4166bb415a128aef), но, похоже, в этом случае результат просто вычисляется во время компиляции:
fld qword ptr [[email protected] (828EA0h)]
fstp qword ptr [f]
Так , как я могу исправить эту проблему?
P.S. Я нашел временное обходное решение (мне нужна только дробная часть деления, поэтому я просто использую f = fmod (a/b)/b на данный момент), но мне все же хотелось бы знать, как правильно исправить эту проблему - double точность должна быть 16 десятичных цифр, поэтому такой расчет не должен вызывать проблем.
Это правильный ответ. Программа использует Direct3D, и, конечно же, расчет происходит после создания устройства. Самое смешное, что я знал о D3D, регулирующем точность FPU, но я полностью забыл об этом, потому что я не видел эту ошибку за последние несколько лет. Проблема решена. – SigTerm
Какой флаг следует использовать при создании устройства? Существует ли такая же проблема с Direct2D? – dalle