comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: float confusion
Date: Tue, 14 Jul 2009 16:50:20 -0700 (PDT)
Date: 2009-07-14T16:50:20-07:00	[thread overview]
Message-ID: <510054e8-9abf-4a6e-87f2-3385e573b1c2@g31g2000yqc.googlegroups.com> (raw)
In-Reply-To: sc2q55185rv4dhc8dk0feu0dvuq7887oul@4ax.com

On Jul 14, 3:46 pm, Rob Solomon <use...@drrob1-noreply.com> wrote:
> I ran this simple example thru GNAT and I'm confused by the result.
>
> -- conclusions from this pgm
> -- integer type does not raise overflow constraint_error
> -- natural and positive types do raise overflow constraint_error when
> -- overflow is by multiplication, but not by addition.
>
> with Ada.Text_IO;
> with Ada.Integer_Text_IO;
> with Ada.Float_Text_IO;
> use Ada.Text_IO;
> use Ada.Integer_Text_IO;
> use Ada.Float_Text_IO;
>
>    procedure SimpleCompute is
>
>    X : Integer := 1;
>    c : Integer := 0;  -- counter
>    N : Natural := 1;
>    P : Positive := 1;
>    F : Float := 1.0;
>
>    begin
>    put_line("X C N P F");
>    loop
>     put(X);
>     card32_IO.put(u2);
>     put(c,3);
>     put(n);
>     put(' ');
>     put(p);
>     put(' ');
>     put(f,15,0,0);
>     New_Line;
>     X := X * 2;
>     n := n * 2;
>     p := p + p;
>     f := f * 2.0;
>     c := c +1;
>     exit when c > 40;
>    end loop;
>    exception
>       when constraint_error =>
>          n := 1;
>    end simplecompute;
>
> My confusion is that float'digits is 6 and long_float'digits is 15 (I
> already checked this).
>
> When I run this code, float grows to the full 13 digits before I stop
> it.  Why is that?

It only appears to.  Put(f,15,0,0) will display as many digits as it
needs to to display the integer part of "f", since you told it not to
display in exponential notation.  Float'Digits is 6, which means you
can count on the float having 6 significant decimal digits.  Any other
decimal digits you see, past the first 6 or 7, will be, in essence,
garbage.  But the Put routine has to display something for those
digits.

The results happen to be correct, but that's only because you're
computing powers of 2, which means that if Put assumes that any bits
dropped of the end of the float are 0, it will be correct.  If you try
modifying the code to do this:

   f := f * 2.0;
   if c > 20 then f := f - 1.0; end if;

you'll see that after f gets to about seven or eight significant
digits, the results will start being wrong, because the 1.0 that
you're trying to subtract will become too small for a float whose
'digits is only 6.

I hope that helps explain things; if you need to know more, you'll
need to start looking into the details of how IEEE 32-bit floats are
implemented.


> And interestingly, I get overflow errors from the *2 statement but not
> from self+self.

How can you tell?  Your above example gives you no way to tell what
line you get an overflow on.  And the way it's written, if you got an
overflow on X := X*2, the exception would take you out of the loop and
you'd never get to the p := p+p statement for the same value (since it
looks like X=n=p will always be true at the beginning of the loop).

                                -- Adam



  parent reply	other threads:[~2009-07-14 23:50 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-14 22:46 float confusion Rob Solomon
2009-07-14 23:23 ` Jeffrey R. Carter
2009-07-14 23:26 ` Randy Brukardt
2009-07-14 23:50 ` Adam Beneschan [this message]
2009-07-15  0:03   ` Rob Solomon
2009-07-15  0:18     ` Adam Beneschan
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox