comp.lang.ada
 help / color / mirror / Atom feed
From: "Alex Mentis" <foo@invalid.invalid>
Subject: Re: Unconstrained base subtype questions
Date: Thu, 31 Mar 2011 21:51:29 +0000 (UTC)
Date: 2011-03-31T21:51:29+00:00	[thread overview]
Message-ID: <in2t10$sfq$1@dont-email.me> (raw)
In-Reply-To: in2rf9$49o$1@munin.nbi.dk

Randy Brukardt wrote:

> "Alex Mentis" <foo@invalid.invalid> wrote in message
> news:in2nv8$v3e$1@dont-email.me...
> > The following does not cause a constraint error in my version of
> > GNAT on my system:
> > 
> > ...
> > 
> > Integer_Result := (Integer'Last + Integer'Last) / 2;
> > 
> > ...
> > 
> > 
> > If I understand correctly, this is because the Integer operators are
> > defined for operands of type Integer'Base, which is an unconstrained
> > subtype and allows the operands to be stored in extended-length
> > registers so that intermediate values in calculations do not
> > overflow.
> 
> Right. In this case, the compiler is probably just doing constant
> folding using unlimited precision numbers. Does the same thing happen
> when you use variables??
> 
>   Last : Integer := Integer'Last;
> 
>   Result : Integer :=  (Last + Last)/2;
> 
> (Even better, write a function that returns Integer'Last and call it;
> the ACATS uses this technique to reduce optimization of expressions.)
> 
> > My questions are:
> > 
> > 1) Do I understand correctly what's going on?
> 
> I think so.
> 
> > 2) Does the language make any guarantees about preventing spurious
> > overflow, or am I just getting lucky with my compiler/architecture?
> > If guarantees are made by the language, what are they?
> 
> The language says effectively that you either will get the right
> answer or Constraint_Error. But it makes no guarantees about which
> you will get for values outside of the result subtype. So that is
> compiler-dependent.
> 
> The intent is to be able to use the hardware effectively. To take an
> example, older Intel X86 processors did all of their floating point
> calculations in 80-bit registers. The only certain way to use fewer
> bits was to store the register into memory and then reload it (which
> forced the needed rounding). Needless to say, this doesn't help
> performance!
> 
> In something like:
>    F := (A * B) / (C * D);
> you would have two extra store/load pairs. That's awful, thus the
> rule allowing extra precision.
> 
> For float types, Ada actually has an attribute to explicitly discard
> extra precision (S'Machine). For integer types, you'd have to
> explicitly store the subexpression into an object and do a validity
> test on it. (It's not clear to me that a type conversion alone would
> guarantee a check for a type like Integer where Integer has the same
> range as Integer'Base. The validity rules always allow delaying a
> constraint check, so only 'Valid is certain to smoke out overflowing
> values.)
> 
> But both of these operations are expensive, and should only be used
> when absolute portability is needed.
> 
>                                  Randy.

Using variables gave me the behavior I was expecting. I didn't know Ada
did infinite precision arithmetic on static expressions.

Thanks,
Alex



  reply	other threads:[~2011-03-31 21:51 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-31 20:25 Unconstrained base subtype questions Alex Mentis
2011-03-31 21:09 ` Ludovic Brenta
2011-03-31 21:26   ` Alex Mentis
2011-03-31 21:36     ` Ludovic Brenta
2011-03-31 22:18       ` Adam Beneschan
2011-03-31 21:10 ` Adam Beneschan
2011-03-31 21:18 ` Simon Wright
2011-03-31 21:24 ` Randy Brukardt
2011-03-31 21:51   ` Alex Mentis [this message]
2011-04-01  8:20     ` Dmitry A. Kazakov
replies disabled

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