Re: Embarrassing Arithmetic behaviour
"Richard A. O'Keefe" <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 21/02/2014, at 9:00 AM, j.gressier wrote:
> I use the C interface of swi to work with Pascal. It all came from this Pascal code (example):
>
> var a,b : double;
> begin
> b := 4.9 * 100000.0 ;
> if b = 490000 then showmessage('true') else showmessage('false') ;
> a := PL_compare_mine(b)
>
> Pascal will answer 'true'. (unlike swi-prolog, C, Gambit... and Python which I have just checked)
Erk.
So the "Embarrassing Arithmetic behaviour" is
clearly happening in *Pascal*, not in Prolog.
Is there a support list for your Pascal system?
I have no idea what Pascal compiler you are using.
There is no 'double' in either of the ISO Pascal standards.
So I cannot speak with authority here about your Pascal
system. Let me tell you about Ada instead.
In Ada, 4.9 is not a floating point literal,
it is a literal of type 'Universal_Fixed' with (in principle)
unbounded precision. Similarly, 100000.0 is also an
(in principle) infinitely precise number. The expression
4.9 * 100000.0 is therefore *not* evaluated with the
floating-point * but with the Universal_Fixed * at compile
time, yielding the (in principle) infinitely precise
490000. When the compiler notices that the Universal_Fixed
constant is being assigned to a double precision floating
point variable, it heaves a sigh of relief (unbounded
precise arithmetic being _only_ a compile-time feature, not
a run-time one) and at that point converts the number to
floating point. And 490000 *is* exactly representable as
a floating point number.
I cannot say for sure, but if you did
var
a, b: double;
begin
b := 4.9;
a := 100000.0;
b := b * a;
a := 490000.0;
if b = a then
showmessage('true');
else
showmessage('false');
end;
you might well get a different answer.
You certainly would in Ada.
It's a general GOTCHA! in statically typed compiled
languages, that arithmetic expressions evaluated at
compile time may be *differently* evaluated than
expressions with the same structure and leaves
evaluated at run time.
Amongst other things, in IEEE the rounding mode can
be changed at run time, so an expression x*y could
give two different results at run time even though
x and y had not changed.