comp.lang.ada
 help / color / mirror / Atom feed
* float confusion
@ 2009-07-14 22:46 Rob Solomon
  2009-07-14 23:23 ` Jeffrey R. Carter
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Rob Solomon @ 2009-07-14 22:46 UTC (permalink / raw)


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?

And interestingly, I get overflow errors from the *2 statement but not
from self+self.  I wonder if this occurs because this kind of overflow
is needed in the computation of random numbers.

Thx



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: float confusion
  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
  2 siblings, 0 replies; 6+ messages in thread
From: Jeffrey R. Carter @ 2009-07-14 23:23 UTC (permalink / raw)


Rob Solomon wrote:
> I ran this simple example thru GNAT and I'm confused by the result.

Did you use the -gnato (integer overflow checking) and -fstack-check switches? 
GNAT is not an Ada compiler without them.

> -- 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.

Note that there is a difference between an overflow check and a range check. 
Natural and Positive (which are subtypes, not types) have range constraints that 
Integer does not; GNAT performs range checks even when overflow checks are not 
enabled.

>     card32_IO.put(u2);

These appear to be undefined.

What output do you expect from the program, and what do you get?

-- 
Jeff Carter
"Whatever it is, I'm against it."
Horse Feathers
46



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: float confusion
  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
  2 siblings, 0 replies; 6+ messages in thread
From: Randy Brukardt @ 2009-07-14 23:26 UTC (permalink / raw)


Did you use -gnato? Gnat doesn't check integer overflow by default (one of 
the worst design decisions in GNAT, IMHO.)

If you are just starting out, you ought to use -gnato -fstack_check on all 
of your compilations in order to get the behavior specified by the standard. 
(To be perfectly like the Ada Standard, you also need to use -gnatE, but 
that is much less likely to cause trouble.)

                                    Randy.

"Rob Solomon" <usenet@drrob1-noreply.com> wrote in message 
news:sc2q55185rv4dhc8dk0feu0dvuq7887oul@4ax.com...
>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?
>
> And interestingly, I get overflow errors from the *2 statement but not
> from self+self.  I wonder if this occurs because this kind of overflow
> is needed in the computation of random numbers.
>
> Thx 





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: float confusion
  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
  2009-07-15  0:03   ` Rob Solomon
  2 siblings, 1 reply; 6+ messages in thread
From: Adam Beneschan @ 2009-07-14 23:50 UTC (permalink / raw)


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



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: float confusion
  2009-07-14 23:50 ` Adam Beneschan
@ 2009-07-15  0:03   ` Rob Solomon
  2009-07-15  0:18     ` Adam Beneschan
  0 siblings, 1 reply; 6+ messages in thread
From: Rob Solomon @ 2009-07-15  0:03 UTC (permalink / raw)


On Tue, 14 Jul 2009 16:50:20 -0700 (PDT), Adam Beneschan
<adam@irvine.com> wrote:

>> 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);
>> � � 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;
>>
>> 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).
>

Ok.  I got this example from the online tutorial and I kept modifying
it to try something new.  Before I experimented w/  exception
handling, I was getting constraint_error exceptions.  

But Jeff Carter above explained that was I was seeing was really range
checking effects and not overflow effects.  That helped me understand
what was going on.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: float confusion
  2009-07-15  0:03   ` Rob Solomon
@ 2009-07-15  0:18     ` Adam Beneschan
  0 siblings, 0 replies; 6+ messages in thread
From: Adam Beneschan @ 2009-07-15  0:18 UTC (permalink / raw)


On Jul 14, 5:03 pm, Rob Solomon <use...@drrob1-noreply.com> wrote:
> On Tue, 14 Jul 2009 16:50:20 -0700 (PDT), Adam Beneschan
>
>
>
>
>
> <a...@irvine.com> wrote:
> >> 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);
> >>     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;
>
> >> 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).
>
> Ok.  I got this example from the online tutorial and I kept modifying
> it to try something new.  Before I experimented w/  exception
> handling, I was getting constraint_error exceptions.  
>
> But Jeff Carter above explained that was I was seeing was really range
> checking effects and not overflow effects.  That helped me understand
> what was going on

Well, maybe.  Jeff said that Natural and Positive have range
constraints that Integer does not; however, those constraints prevent
objects from having negative values (or zero, for Positive), and since
your program is working only with positive numbers, that shouldn't
have had an effect.  However, if you don't have overflow checking on (-
gnato), then what happens is that when you get to the largest possible
power of 2, which is 2**30 for a 32-bit integer, and then double it,
the result will be seen as negative (-2**31), which (without overflow
checking) will cause a Constraint_Error for a Natural or Positive but
no exception at all for an Integer.  So in your example, this would
mean "n:=n*2" and "p:=p+p" would have raised exceptions, but "X:=X*2"
would not.  So I'm still not clear on why you'd think this is a
difference between multiplication and addition, unless you were
experimenting with different code earlier.

                                   -- Adam




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-07-15  0:18 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2009-07-15  0:03   ` Rob Solomon
2009-07-15  0:18     ` Adam Beneschan

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