Maxima比较相等的列表元素差值时返回false问题求助
问题产生原因
这是典型的二进制浮点数精度误差问题:
- 十进制的0.1、0.2这类小数无法用二进制浮点数精确表示,存储时会做截断处理,存在微小的固有误差
- 两次差值计算的实际结果本身就存在极细微的差异,只是Maxima默认的打印精度做了四舍五入,才会都显示为0.1
- 你可以通过调整打印精度查看实际差值,执行
fpprintprec:20$后重新计算两个差值,就能看到二者的具体差异
对应的解决办法
有三种常用的方案可以解决该问题:
- 采用容差比较替代绝对等值判断
不要直接使用=判断浮点数相等,改为判断两个值的差是否小于可接受的误差阈值,示例代码如下:
is(abs((pointsx[2]-pointsx[1]) - (pointsx[3]-pointsx[2])) < 1e-12);
上述代码会返回你预期的true。
- 用精确有理数存储数值
定义列表时直接用分数形式表示所有数值,避免浮点数截断误差,示例定义如下:
pointsx:[1/10, 2/10, 3/10, 4/10, 13/20, 9/10]$
此时做差值的等值判断会完全精确,直接用=对比也会返回true。
- 启用Maxima的带容差等值判断
可以直接使用equal函数替代=运算符,equal在对比浮点数时会自动使用内置的容差阈值ratepsilon判断近似相等,示例代码如下:
is(equal(pointsx[2]-pointsx[1], pointsx[3]-pointsx[2]));
内容的提问来源于stack exchange,提问作者Nicolás Fernández
相关产品推荐
相关产品推荐

