wxMaxima中浮点数使用equal的最佳实践及近似相等判断方法
问题根因
返回false的本质是二进制浮点数精度误差:0.1无法被二进制浮点数精确表示,多次累加后x1的最后一个元素、x2的第一个元素会和预设的a:-0.2产生微小的舍入差异,直接全等比较自然不相等。
可用处理策略
1. 使用Maxima自带的近似相等比较函数
Maxima内置了almost_equal函数,就是你要的支持指定精度的equal变体,用法如下:
/* 第三个参数为允许的最大绝对误差,可根据业务场景调整 */ is(almost_equal(last(x1), first(x2), 1e-6));
如果需要适配未知数量级的数值,可改用相对误差判断:
/* 允许1e-6的相对误差,自动适配数值大小 */ is(almost_equal(last(x1), first(x2), 1e-6 * max(abs(last(x1)), abs(first(x2)))));
2. 自动将输入浮点数转为精确有理数
无需手动修改输入格式,用rationalize函数把浮点数转成精确的分数形式再运算,从根源消除精度误差:
/* 对所有输入的浮点数做精确转换 */ xi: rationalize(-8)$ a: rationalize(-0.2)$ dx: rationalize(0.1)$ xf: rationalize(8)$ x1:makelist(i,i, xi, a, dx)$ x2:makelist(i,i, a, xf, dx)$ /* 此时直接equal比较也会返回true */ is(equal(last(x1), first(x2)));
3. 序列衔接对齐处理
如果是生成两段衔接的序列,直接用前一段的尾值作为后一段的起始值,避免两边独立累加的误差错位:
x1:makelist(i,i, xi, a, dx)$ /* 直接用last(x1)作为x2的起点 */ x2:makelist(i,i, last(x1), xf, dx)$
内容的提问来源于stack exchange,提问作者Rax Adaam
相关产品推荐
相关产品推荐

