对于双精度,(x - x)是否始终为正零,或者有时为负零?
什么时候是 ,何时保证是 ,或者有时可能是(取决于 )的符号?x
double
(x - x)
+0.0
-0.0
x
什么时候是 ,何时保证是 ,或者有时可能是(取决于 )的符号?x
double
(x - x)
+0.0
-0.0
x
x - x
可以是 或 。在IEEE 754算术中,它没有其他值可以舍入到最接近(在Java中,舍入模式始终是舍入到最近)。两个相同的有限值的减法被定义为在此舍入模式下产生。马克·迪金森(Mark Dickinson)在下面的评论中引用了IEEE 754标准,第6.3节:+0.0
NaN
+0.0
当具有相反符号的两个操作数之和(或两个具有类似符号的操作数的差值)正好为零时,该和(或差值)的符号在所有舍入方向属性中应为 +0,除了 roundTowardNegative [...]。
此页面显示,特别是 和 两者兼而有之。0.0 - 0.0
-0.0 - (-0.0)
+0.0
无穷大和 NaN 在从自身中减去时都会产生 NaN。
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
roundNearestTiesToEven
请注意舍入模式的反例:http://rise4fun.com/Z3/T845。对于某个,结果为负零。人类很难找到这样的案例。然而,使用SMT求解器很容易找到。我们可以更改为 Z3 使用 IEEE 相等比较语义,而不是精确相等。在那次改变之后,再次没有反例,因为根据IEEE。roundTowardNegative
x
x - x
=
==
-0 == +0
我尝试将舍入模式设置为变量。这在理论上是可行的,但Z3在这里有一个错误。现在,我们必须手动指定硬编码的舍入模式。如果我们能使它成为一个变量,我们可以要求 Z3 在一个查询中证明所有舍入模式的此语句。