Nic*_*ick 19 floating-point matlab
我试图理解MATLAB中基本算术运算的舍入误差,我遇到了以下奇怪的例子.
(0.3)^3 == (0.3)*(0.3)*(0.3)
ans = 0
Run Code Online (Sandbox Code Playgroud)
我想确切地知道如何计算左侧.MATLAB文档表明,对于整数幂,使用"通过平方取幂"算法.
"矩阵功率.如果p是标量,则X ^ p是功率p的X.如果p是整数,则通过重复平方来计算功率."
所以,我认为(0.3)^3并(0.3)*(0.3)^2会返回相同的值.但这种情况并非如此.如何解释舍入误差的差异?
我对MATLAB一无所知,但我在Ruby中尝试过:
irb> 0.3 ** 3
=> 0.026999999999999996
irb> 0.3 * 0.3 * 0.3
=> 0.027
Run Code Online (Sandbox Code Playgroud)
根据Ruby源代码,如果左侧操作数是浮点数,则取幂运算符将右侧操作数转换为浮点数,然后调用标准C函数pow().函数的float变体pow()必须实现更复杂的算法来处理非整数指数,这将使用导致舍入误差的操作.也许MATLAB的工作方式类似.
感谢@Dougal,我发现了这个:
#include <stdio.h>
int main() {
double x = 0.3;
printf("%.40f\n", (x*x*x));
long double y = 0.3;
printf("%.40f\n", (double)(y*y*y));
}
Run Code Online (Sandbox Code Playgroud)
这使:
0.0269999999999999996946886682280819513835
0.0269999999999999962252417162744677625597
Run Code Online (Sandbox Code Playgroud)
这种情况很奇怪,因为更多位数的计算给出了最差的结果。这是因为无论如何初始数字 0.3 都是用几个数字来近似的,因此我们从一个相对“大”的误差开始。在这种特殊情况下,发生的情况是,用几个数字进行的计算给出了另一个“大”误差,但符号相反......因此补偿了初始误差。相反,使用更多位数的计算会给出第二个较小的误差,但第一个误差仍然存在。