x<=y 和 x-y<=0 在浮点运算中是不是等效?

Posted

技术标签:

【中文标题】x<=y 和 x-y<=0 在浮点运算中是不是等效?【英文标题】:Are x<=y and x-y<=0 equivalent in floating point arithmetic?x<=y 和 x-y<=0 在浮点运算中是否等效? 【发布时间】:2014-10-18 18:21:17 【问题描述】:

假设 x,y 是两个浮点数。那是真的吗:

x<=y <==> x-y<=0

在浮点运算中?

感谢您的想法。

[编辑] 另外让我们假设 x 和 y 都不是NaN

是否有可能 x

【问题讨论】:

@Paul R:现在排除了 NaN 情况(参见上面的编辑),所以我的问题更多是关于处理“正常”浮点数。 唯一重要的 NaN 情况是 x == y 并且两者都是无穷大。 【参考方案1】:

[注意:我在这个答案中忽略了无穷大和 NaN,因为两者都会导致不等价。]

如果您禁用了次正规数(或清零行为),那么减法可能会产生下溢,从而导致两个表达式之间不等价。

例如:

#include <stdio.h>
#define CSR_FLUSH_TO_ZERO (1 << 15)

// Note: GCC-specific
void disable_ftz(void) 
    unsigned csr = __builtin_ia32_stmxcsr();
    csr |= CSR_FLUSH_TO_ZERO;
    __builtin_ia32_ldmxcsr(csr);


int main(void) 
    disable_ftz();

    float x = 2.8e-45;
    float y = 1.4e-45;

    printf("%e\n", x);           // 2.802597e-45
    printf("%e\n", y);           // 1.401298e-45

    printf("%d\n", x <= y);      // 0
    printf("%d\n", (x-y) <= 0);  // 1
    return 0;

请注意,这需要 x86 上的一些特定于编译器的魔法。但是,允许有一个根本没有次正规的浮点实现,并且在这样的系统上实现相同的不等价不需要任何魔法。

【讨论】:

如果你有逐渐下溢,减法显然是不可能的;这就是逐渐下溢的关键。 @tmyklebu:当然,但“逐渐下溢”(AKA 非正规)有其局限性。当然,产生小于最小非正规数的唯一方法是使 xy 相差该值,这是不可能的:)

以上是关于x<=y 和 x-y<=0 在浮点运算中是不是等效?的主要内容,如果未能解决你的问题,请参考以下文章

算数运算符

shell 算术运算符

JavaScript 赋值

python的三元运算

[python]运算符与表达式

JavaScript运算符及数据类型