提问人:cheng 提问时间:5/7/2015 更新时间:5/7/2015 访问量:869
浮点加法/乘法/除法
Floating Point Addition / Multiplication / Division
问:
我正在做教科书中的一些家庭作业,并且对某些算术运算的浮点舍入/精度有一些问题。
如果我像这样从 int 中转换双打:
int x = random();
double dx = (double) x;
假设变量 y、z、dy 和 dz 遵循相同的格式。
然后会像这样操作:
(dx + dy) + dz == dx + (dy + dz)
(dx * dy) * dz == dx * (dy * dz)
有关联性吗?我知道,如果我们有分数表示,那么它就不会是关联的,因为根据哪些操作数相互相加/相乘,舍入会损失一些精度。但是,由于这些是从 ints 转换的,我觉得精度不会成为问题,而且这些可以关联吗?
最后,我使用的教科书根本没有解释 FP 除法,所以我想知道这种说法是否正确,或者至少只是浮点除法的一般工作原理:
dx / dx == dz / dz
我在网上查了一下,我在某些领域读到过,比如像 3/3 这样的操作可以产生 .999...9,但没有足够的信息来解释这是如何发生的,或者它是否会因其他部门操作而异。
答:
假设最多为 32 位,并遵循 IEEE-754。 最多可以精确存储 253 个整数值。int
double
double
在添加的情况下:
(dx + dy) + dz == dx + (dy + dz)
两边都有其精确的值,因此它是关联的。==
而在乘法的情况下:
(dx * dy) * dz == dx * (dy * dz)
该值可能超过 253,因此不能保证它们相等。
评论
double
-pow(2,53) ... +pow(2,53)
int54_t
您应该了解,浮点数通常在内部表示为符号位、定点尾数(52 位,IEEE 64 位双精度的隐含前导数)和二进制指数(IEEE 双精度的 11 位)。您可以将指数视为给定值的数学单位的“量子”。
如果总和都适合尾数,而指数没有超过 20 == 1,则加法应该是关联的。如果生成 32 位整数,则总和(如 将拟合),并且加法将是关联的。random()
(dx + dy) + dz
在乘法的情况下,很容易看出 2 个 32 位数字的乘积可能远远超过 53 位,因此指数可能需要大于 1 才能使尾数包含结果的大小,因此关联性失败。
对于除法,在特定情况下,编译器可能会用常量 1.0 替换表达式(可能在零检查之后)。dx / dx
评论
(dx * dy) * dz == dx * (dy * dz)
如果精度<精度的两倍,则会出现问题 - 这通常是这种情况。 不太可能成为问题,因为精度肯定超过精度 + 1。 明显的问题应该或.double
int
(dx + dy) + dz == dx + (dy + dz)
double
int
dx / dx == dz / dz
dx==0
dz==0
dx * dy
dy * dz
2^53
double dx = (double)(INT_MAX); double dy = (double)(INT_MAX - 0x111111); double dz = (double)(INT_MAX - 0xabcd);
(dx * dy) * dz == dx * (dy * dz)