Marcello Impastato
Marcello Impastato

Reputation: 2281

Why does calculation using real give different result from one using int?

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

Answers (5)

Jørn E. Angeltveit
Jørn E. Angeltveit

Reputation: 3079

You should also take a look at Rudy Velthuis' article:

http://rvelthuis.de/articles/articles-floats.html

Upvotes: 1

Rob Kennedy
Rob Kennedy

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

Ken Bourassa
Ken Bourassa

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

David Hammen
David Hammen

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

Andreas Rejbrand
Andreas Rejbrand

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

Related Questions