Reputation: 2281
I have this code for example:
(a) writeln ('real => ', exp(3*Ln(3)):0:0); // return 27
(b) writeln ('int => ', int(exp(3*Ln(3))):0:0); // return 26
Is a bug? The function calc 3^3 (exponent using ln and exp function), but conversion from real to int fail; in case (a) return 27, in case (b) return (26), when should be 27 both. As i can solve it? Thanks very much for help.
Ps: Too assign result to integer variable, using trunc, result not change.
Upvotes: 1
Views: 454
Reputation: 3079
You should also take a look at Rudy Velthuis' article:
http://rvelthuis.de/articles/articles-floats.html
Upvotes: 1
Reputation: 163357
The expression you're printing evaluates to something slightly less than 27 due to the usual floating-point errors. The computer cannot exactly represent the natural logarithm of 3, so any further calculations based on it will have errors, too.
In comments, you claim exp(3*ln(3)) = 27.000, but you've shown no programmatic evidence for that assertion. Your code says exp(3*ln(3)) = 27, which is less precise. It prints that because you explicitly told WriteLn
to use less precision. The :0:0
part isn't just decoration. It means that you want to print the result with zero decimal places. When you tell WriteLn
to do that, it rounds to that many decimal places. In this case, it rounds up. But when you introduce the call to Int
, you truncate the almost-27 value to exactly 26, and then WriteLn
trivially rounds that to 26 before printing it.
If you tell WriteLn
to display more decimal places, you should see different results. Consult the documentation for Write
for details on what the numbers after the colons mean.
Upvotes: 6
Reputation: 6502
Working with floating points doesn't always give a 100% exact result. The reason being is that binary floating points variable can't always represent values exactly. The same thing is true about decimal numbers. If you take 1/3, in a 6 digit precision decimal, would be 0.333333. Then if you take 0.333333 * 3 = 0.999999. Int(0.999999) = 0
Here is some litterature about it...
What Every Computer Scientist Should Know About Floating-Point Arithmetic
Upvotes: 2
Reputation: 33126
Not a bug. It is just yet another example of how floating arithmetic works on a computer. Floating point arithmetic is but an approximation of how the real numbers work in mathematics. There is no guarantee, and there can be no such guarantee, that floating point results will be infinitely accurate. In fact, you should expect them to almost always be imprecise to some degree.
Upvotes: 0
Reputation: 109003
No, it is not a bug. Computers simply don't have infinite precision, so the result is not exactly 27, but perhaps 26.999999999 or something. And so, when you int
or trunc
it, it ends up as 26. Use Round
instead.
Upvotes: 10