c – 关于浮点数关系运算符的否定的断言

假设我有两个变量a和b,要么都是float类型,要么都是double类型,它们包含一些值.以下断言是否始终存在?我的意思是,数值误差的存在会改变结论吗?

a > b is true if and only if a <= b is false

a < b is true if and only if a >= b is false

a >= b is necessarily true if a == b is true

a <= b is necessarily true if a == b is true

对于第三和第四,我的意思是,例如,“a == b是真的”总是给你“a> = b是真的”吗?

编辑:

假设a或b都不是NaN或Inf.

编辑2:

在1985年阅读IEEE 754标准后,我发现了以下内容.

首先,它说了以下内容

Comparisons are exact and never overflow nor underflow.

我理解为比较时,没有考虑数值误差,数字按原样进行比较.由于诸如a-b之类的加法和减法需要额外的努力来定义数值误差是什么,我假设上面引用的是比较像> b不是通过判断是否a-b>来完成的. 0是真是假.如果我错了,请告诉我.

其次,列出了相互排斥的四种规范关系.

Four mutually exclusive relations are possible: less than, equal, greater than, and unordered. The last case arises when at least one operand is NaN. Every NaN shall compare unordered with everything, including itself.

然后在表4中,它定义了各种运算符,例如“>”或者“> =”就这四种规范关系下的真值而言.从表中我们立即得到以下信息:

a >= b is true if and only if a < b is false

a <= b is true if and only if a > b is false

Both a >= b and a <= b are necessarily true if a == b is true

因此,我的问题中的断言可以归结为真实.但是,我无法在标准中找到任何定义对称性是否正确的内容.换句话说,来自> b我不知道b< a是真是假.因此,我也无法从b< = b得到< = b是真的. a是假的.所以我很想知道,除了OP中的断言之外,以下是否总是正确的

a < b is true if and only if b > a is true

a <= b is true if and only if b >= a is true

etc.

编辑3:

关于@Mark Ransom提到的非正规数,我阅读了关于它的维基百科页面,我目前的理解是,非正规数的存在不会改变上面的结论.换句话说,如果某些硬件声称它完全支持非正规数,则还需要确保比较运算符的定义满足上述标准.

编辑4:

我刚刚阅读了IEEE 754的2008版本,它也没有说明对称性.所以我猜这是未定义的.

(以上讨论都假设任何操作数都没有NaN或Inf).

最佳答案 如果你有一个IEEE兼容系统,如果这两个数字都不是NaN或无穷大,那么你的断言就会成立.如果标准没有提到它,那么我确信这只是因为它足够明显而不值得一提.特别是,如果“a< b”和“b> a”不具有相同的值(即使对于NaN和无穷大),那么我们处于疯狂的城镇.

非正规不应该影响结论,因为如果你假设IEEE兼容性,那么非正规支持是给定的.

我能想到的唯一风险是涉及x87 FPU和奇怪的80位长双格式的情况.从80位长双精度舍入到双精度或浮点数很昂贵,因此有时会省略它,这可能会导致像这样的触发断言:

assert(sqrt(val) == sqrt(val));

它可能会触发,因为第一个sqrt()调用的结果可能会写入内存,因此舍入为float或double.然后将它与第二个sqrt()调用的结果进行比较,该结果可能不会被舍入.但是,如果sqrt()返回float或double,则在进行比较之前未能对第二个sqrt()调用的结果进行舍入,严格来说,不符合IEEE标准.

如果两个数字都是无穷大,则无穷大应该只是一个问题.

点赞