(x - x)对于双精度是否总是正零,或者有时负零?

时间:2014-07-25 08:06:25

标签: java floating-point

xdouble时,(x - x)保证为+0.0,有时可能为-0.0(取决于x的符号1}})?

2 个答案:

答案 0 :(得分:60)

x - x可以是+0.0NaN。 IEEE 754算术中没有其他值可以采用舍入到最接近的值(在Java中,舍入模式为always round-to-nearest)。在此舍入模式中,两个相同有限值的减法定义为生成+0.0Mark Dickinson,在下面的评论中,引用了IEEE 754标准,第6.3节:

  

当具有相反符号的两个操作数的总和(或具有相同符号的两个操作数的差异)恰好为零时,除了roundTowardNegative [之外],在所有舍入方向属性中该和(或差)的符号应为+0。 ..]。

page表示特别是0.0 - 0.0-0.0 - (-0.0)都是+0.0

无穷大和NaN都会从自身中减去NaN。

答案 1 :(得分:9)

SMT求解器Z3支持IEEE浮点运算。让我们让Z3找一个x - x != 0的案例。它会立即找到NaN以及+-infinity。除此之外,没有x满足该等式。

(set-logic QF_FPA)    

(declare-const x (_ FP 11 53))
(declare-const r (_ FP 11 53))

(assert (and 
    (not (= x (as NaN (_ FP 11 53))))
    (not (= x (as plusInfinity (_ FP 11 53))))
    (not (= x (as minusInfinity (_ FP 11 53))))
    (= r (- roundTowardZero x x))
    (not (= r ((_ asFloat 11 53) roundTowardZero 0.0 0)))
))

(check-sat)
(get-model)

Z3通过将所有操作转换为布尔电路并使用标准SAT求解器来查找模型来实现IEEE浮点算法。除非该翻译或SAT求解器中的任何错误,结果都非常精确。

证明...

请注意舍入模式roundTowardNegative的反例:http://rise4fun.com/Z3/T845。对于某个xx - x的结果为负零。人类很难找到这种情况。然而,使用SMT求解器很容易找到。我们可以将=更改为==,以便Z3使用IEEE等式比较语义而不是精确相等。在那次改变之后,再没有反例,因为根据IEEE的-0 == +0

我尝试将舍入模式变为变量。这在理论上是有效的,但Z3在这里有一个错误。现在我们必须手动指定硬编码的舍入模式。如果我们可以将其变为变量,我们可以要求Z3在一个查询中为所有舍入模式证明此语句。