Z3 - 浮点运算 API 函数 Z3_mk_fpa_to_ubv

Z3 - Floating point arithmetic API function Z3_mk_fpa_to_ubv

我是第一次玩 Z3-4.6.0 C++。对不起,菜鸟问题。

我的问题分为两部分。

如果我有一个浮点数,我使用 Z3_mk_fpa_to_ubv(...) 函数创建一个无符号位向量。

  1. 损失了多少精度?
  2. 如果精度没有丢失,我可以使用这个新的无符号位向量作为常规位向量并应用为其定义的所有操作,例如 Z3_mk_bvadd(.. ..)?

我知道我可以使用 Z3_mk_fpa_to_ieee_bv(....) 进行优雅且符合 IEEE-754 的转换。之后我可以添加、子等位向量。

只是好奇。

非常感谢。

恐怕您误解了这些函数的作用。在使用 SMTLib 浮动时保持打开状态的一个很好的参考是:http://smtlib.cs.uiowa.edu/papers/BTRW15.pdf

mk_fpa_to_ubv

此函数对应于引用论文中的FPToUInt函数。定义如下:

(上面的 NaN 选择具有误导性:应读作 "undefined.")

请注意,这里的精度损失可能很大,具体取决于 FP 值和向量的 bit-width。想象一下将一个 double-precision 浮点值转换为一个 8 位字:您将 ±2.23×10^−308 到 ±1.80×10^308 范围内的值粉碎为仅仅 256 个不同的值。这意味着大量转化将简单地经过大量舍入取消。

您应该将其视为 "casting" 在类似 C 的语言中:

unsigned char c;
double f;
c = (char) f;

这是从double-precision转换为无符号字节的本质,这将遭受重大的精度损失。在另一个方向上,如果你转换为一个非常大的 bit-vector(比如有一千位),那么你的转换仍然会根据舍入模式失去精度,尽管你将能够涵盖所有范围内的整数值。所以,这真的取决于你转换成什么 BV-type 和你选择的舍入模式。

mk_fpa_to_ieee_bv

此函数与"preserving"值无关。所以在这里问 "precision loss" 是无关紧要的。它的作用是根据 IEEE-754 规范为您提供 floating-point 值的基础 bit-vector 表示。维基百科文章对此表示进行了很好的讨论:https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64

特别是,如果您将此函数的输出解释为二进制补码整数值,您将得到一个与 floating-point 数字本身的值无关的完全不相关的值。 (此外,此转换不是唯一的,因为 NaN 有多个对应的 bit-vector 模式。)

总结

长话短说,从浮点数到 bit-vectors 的转换将遭受精度损失,这不仅是因为舍入导致丢失了 "fractional" 部分,而且还因为范围有限,除非你选择 very-large bit-vector 尺码。 IEEE-754 表示转换 not 保留值,因此对通过此函数转换的值进行算术或多或少没有意义。