Значение в f1
и значение в d2
представляют одно и то же число. Это число не точно 42.480000, и при этом это не точно 42.479999542236328, хотя у него есть десятичное представление, которое заканчивается. При отображении чисел с плавающей запятой ваш отладочный вид заметно округляется с точностью до числа с плавающей запятой, а при отображении двойных округляется с точностью до двойного. Таким образом, вы видите вдвое больше значащих цифр мистического значения при конвертации и отображении в виде двойного числа.
d1
содержит лучшее приближение к 4.48, чем таинственное значение, поскольку d1
содержит ближайший двойник к 4.48, тогда как f1
и d2
содержат только ближайшее значение к 4.48. Что вы ожидали от d2
? f1 не может «помнить», что это «действительно должно быть» 4.48, поэтому, когда он конвертируется в удвоение, он становится «более точным».
Способ избежать этого зависит от того, какие серьезные числовые проблемы вы имеете в виду. Если проблема в том, что d1 и d2 не сравниваются одинаково, и вы думаете, что они должны сравниваться, то ответ заключается в том, чтобы включить в ваши сравнения небольшой допуск, например, заменить d1 == d2
на:
fabs(d1 - d2) <= (d2 * FLT_EPSILON)
Это всего лишь пример, хотя я не проверял, имеет ли он дело с этим делом. Вы должны выбрать допустимое отклонение, которое вам подходит, и вам, возможно, придется беспокоиться о множестве крайних случаев - d2 может быть нулем, либо значение может быть бесконечностью, либо NaN, возможно, другие.
Если проблема в том, что d2 не является достаточно точным значением для вашего алгоритма для получения точных результатов, тогда вам следует избегать значений float
и / или использовать более численно устойчивый алгоритм.