首页 > 解决方案 > 为什么除法比乘以它的倒数更准确

问题描述

为什么 X/Y != X*(1/Y)?

为什么 X/Y 比 X*(1/Y) 更准确?

在我的矩阵逆的 C 编码中,我需要做

   inv(inp) = [d -b; -c a]*(1/det(inp));

我通过两种方式做到了,

情况1:

temp = 1/det(inp);
 inv(inp) = [d -b; -c a]*temp;

案例2:

 inv(inp) = [d/det(inp) -b/det(inp); -c/det(inp) a/det(inp)];

与案例 2 中的零错误相比,为什么案例 1 有错误。

提前致谢。

标签: c

解决方案


考虑1/41.f。在实数数学中,1 除以 41 产生有理数 1/41。此数字不能以二进制浮点格式表示。在通常用于float(IEEE-754 单精度)的格式中,我们可以得到的最接近 1/41 的格式是 13094412•2 -29。因此,如果det(inp)是 41,并且您正在使用float,则temp = 1/det(inp);设置temp为 13094412•2 -29。其中的 13094412 部分称为有效数字。

然后,如果我们计算41*temp,实数数学中的结果将是 536870892•2 -29。该float格式仅支持 24 位有效位,因此我将重新调整此结果以使有效位低于 2 24: 16777215.375•2 -5。正如我们所见,有效数字不是整数,因此它不适合float表示。最接近的可表示值为 16777215•2 -5,即 0.999999940395355224609375。

因此,在这种情况下,41*(1/det(inp))将给出 0.999999940395355224609375,而41/det(inp)给出 1。

每当您执行给出浮点结果的操作时,实数数学结果将四舍五入为可表示的结果。这种舍入会引入一个小错误。在多个操作过程中,这些错误可能会以各种方式复合、取消或相互作用。通过计算行列式的倒数,您引入了直接除以行列式时不存在的错误。

(错误可以取消,因为有时一个操作中的舍入恰好与早期操作中的舍入方向相反。因此,有时即使各个操作都有错误,您也可以获得正确的结果。)


推荐阅读