比较C中的浮点数

时间:2011-08-10 09:36:04

标签: c comparison floating-point zero

我有double打印为0.000000,我正在尝试将其与0.0f进行比较,但未成功。为什么这里有区别?确定你的双倍是否为零的最可靠方法是什么?

4 个答案:

答案 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;
}