在千里马我做:
(%i1) 1.4*28;
(%o1) 39.2
(%i2) is(1.4*28=39.2);
(%o2) false
这对我来说很奇怪,但可能与老鼠更换有关?
有没有办法让maxima为'输入'返回'true'
is(1.4*28=39.2);
?
答案 0 :(得分:3)
为什么我的数字,如0.1 + 0.2加起来不是很好的一轮0.3,而且 相反,我得到一个奇怪的结果,如 0.30000000000000004吗
因为在内部,计算机使用a 格式(二进制浮点) 无法准确表示一个数字 像0.1,0.2或0.3一样。
编译代码时 解释,你的“0.1”已经存在 四舍五入到最接近的数字 格式,这导致一个小的 甚至在之前的舍入错误 计算发生了。
在你的情况下,1.4和39.2都不能完全表示为二进制分数,并且计算结果的舍入方式与文字39.2不同。
如果您想避免此类问题,则必须避免使用二进制浮点数。我认为在千里马中,使用适当的分数最容易做到这一点:
is(14/10 * 28 = 392/10)
应该有效
答案 1 :(得分:3)
由于“常规”计算器会将这些问题弄错,有时候,目前还不清楚什么才能真正解决您的问题。如果您正在设置一个自动算术测试,以确定人们是否能得到正确的答案,那么您应该测试的可能是达成一定的容差。
(你的计算器的例子可以通过计算1.0 / 3.0的变化然后乘以3来构建。你可能会得到0.9999 ......。有些计算器比其他计算器更好,所以示例必须稍微更微妙。如1.0 /30.0 X 30.0)
回到千里马,你可以测试看看abs(a-b)<宽容,或许 abs((a-b)/ max(a,b))< relativetolerance。
现在,如果能真正解决问题的是OUTPUT上的精度会降低,那么你可以 只需设置fpprintprec:5即可获得5位十进制数字(四舍五入)。
另一种方法是读取您的数字,以便3.1实际上永远不会转换为二进制,但最初解析为3 + 1/10。从那时起,所有理性算术都可以完全完成。 (有理算术不包括平方根,日志,余弦......,只是+ - * /和整数幂)。这不是Maxima现在的一部分。
顺便说一句,你的0.1 + 0.2的例子在wxmaxima的显示中显示为0.3。但它隐藏了实际价值,因为%-3 / 10实际上并非零。 和fpprec一起玩:50;我们可以用二进制表示0.3,但是输入0.3b0可以表示更多的数字。
0.1 + 0.2-0.3b0; 给出4.440892098500626161694526672363281263363823550461b-17
哦,如果您担心有关Maxima转换的消息 浮动到有理数,设置ratprint:false。它不会改变计算,只会改变警告。