开发者

maxima CAS: float rat replaced

in Maxima I do:

(%i1) 1.4*28;

(%o1) 39.2

(%i2) is(1.4*28=39.2);

(%o2开发者_JAVA技巧) false

This is strange to me, but probably has to do with rat replace?

Is there a way to let maxima return 'true' to the input of is(1.4*28=39.2);?


From The Floating-Point Guide:

Why don’t my numbers, like 0.1 + 0.2 add up to a nice round 0.3, and instead I get a weird result like 0.30000000000000004?

Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all.

When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens.

In your case, both 1.4 and 39.2 are not exactly representable as a binary fraction and the result of the computation ends up being rounded differently than the literal 39.2.

If you want to avoid such issues, you'll have to avoid the use of binary floats. I think in Maxima, this is most easily done by using proper fractions:

is(14/10 * 28 = 392/10)

should work


Since "regular" calculators will get such questions wrong, sometimes, it is not clear what will truly solve your problem. If you are setting up an automated arithmetic test to see if people can get the right answer, then maybe what you should be testing for is agreement up to some tolerance.

(examples for your calculator can be constructed by computing variations of 1.0/3.0 and then multiplying by 3. You might get 0.9999... . Some calculators round better than others, so the examples must be slightly more subtle. Like 1.0/30.0 X 30.0)

Getting back to Maxima, you can test to see if abs(a-b)< tolerance, or perhaps abs((a-b)/max(a,b)) < relativetolerance.

Now if what would really solve your problem is just less precision on OUTPUT, you could just set fpprintprec:5 to get 5 decimal digits (rounded).

An alternative is to read your numbers so that 3.1 in fact never gets converted to binary, but is initially parsed as 3+1/10. From that point on, all rational arithmetic can be done exactly. (Rational arithmetic does not include square roots, logs, cosine..., just +-*/ and integer powers). This is not part of Maxima right now.

Incidentally, your example of 0.1+0.2 shows up as 0.3 in wxmaxima's display. But it is concealing the actual value, because %-3/10 is not, in fact, zero. playing with fpprec:50; we can represent 0.3, still in binary, but to lots more digits by typing 0.3b0.

0.1+0.2-0.3b0; gives 4.440892098500626161694526672363281263363823550461b-17

oh, in case you are concerned by the messages about Maxima converting floats to rational numbers, set ratprint:false. It doesn't change the computing, just the warnings.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜