我有double
打印为0.000000
,我正在尝试将其与0.0f
进行比较,但未成功。为什么这里有区别?确定你的双倍是否为零的最可靠方法是什么?
答案 0 :(得分:20)
要确定它是否接近于零,它将打印为0.000000
到六位小数,如:
fabs(d) < 0.0000005
但是,处理浮点计算中的小不准确性一般会变得非常复杂。
如果您想更好地了解自己的价值,请尝试使用%g
代替%f
进行打印。
答案 1 :(得分:4)
你可以做一个范围。像-0.00001&lt; = x&lt; = 0.00001
答案 2 :(得分:4)
这是现代计算机上浮点运算的基本问题。它们本质上是不精确的,无法可靠地进行比较。例如,语言ML明确禁止对真实类型进行相等比较,因为它被认为太不安全了。另请参阅David Goldberg关于此主题的优秀(如果有点长且以数学为导向)paper。
编辑:tl;博士:你可能做错了。
答案 3 :(得分:1)
此外,一个经常被忽略的浮点数特征是非规范化数字。 这是具有最小指数的数字,但不适合0.5-1范围。
对于浮点数,这些数字低,对于FLL_MIN, 。
使用阈值的一个常见错误是比较两个值,或使用FLT_MIN / DBL_MIN作为限制。
例如,这会导致非逻辑结果(如果您不了解非正规):
bool areDifferent(float a, float b) {
if (a == b) return false; // Or also: if ((a - b) == FLT_MIN)
return true;
}
// What is the output of areDifferent(val, val + FLT_MIN * 0.5f) ?
// true, not false, even if adding half the "minimum value".
Denormals通常也意味着计算中的性能损失。 但是,您无法禁用它们,否则此类代码仍可能产生DIVIDE BY ZERO浮点异常(如果已启用):
float getInverse(float a, float b) {
if (a != b)
return 1.0f / (a-b); // With denormals disabled, a != b can be true, but (a - b) can still be denormals, it'll rounded to 0 and throw the exception
return FLT_MAX;
}