当x
为double
时,(x - x)
保证为+0.0
,有时可能为-0.0
(取决于x
的符号1}})?
答案 0 :(得分:60)
x - x
可以是+0.0
或NaN
。 IEEE 754算术中没有其他值可以采用舍入到最接近的值(在Java中,舍入模式为always round-to-nearest)。在此舍入模式中,两个相同有限值的减法定义为生成+0.0
。 Mark 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求解器中的任何错误,结果都非常精确。
证明...
roundTowardZero
:http://rise4fun.com/Z3/7H4 roundNearestTiesToEven
:http://rise4fun.com/Z3/Opl4W 请注意舍入模式roundTowardNegative
的反例:http://rise4fun.com/Z3/T845。对于某个x
,x - x
的结果为负零。人类很难找到这种情况。然而,使用SMT求解器很容易找到。我们可以将=
更改为==
,以便Z3使用IEEE等式比较语义而不是精确相等。在那次改变之后,再没有反例,因为根据IEEE的-0 == +0
。
我尝试将舍入模式变为变量。这在理论上是有效的,但Z3在这里有一个错误。现在我们必须手动指定硬编码的舍入模式。如果我们可以将其变为变量,我们可以要求Z3在一个查询中为所有舍入模式证明此语句。