comp.lang.ada
 help / color / mirror / Atom feed
* Simple program to find average of 3 numbers
@ 2003-07-04  5:01 prashna
  2003-07-04  5:22 ` John R. Strohm
                   ` (4 more replies)
  0 siblings, 5 replies; 28+ messages in thread
From: prashna @ 2003-07-04  5:01 UTC (permalink / raw)


Hi friends,

What is wrong in the following program which is giving constraint error?

procedure average is 
   type ONE_TO_100 is range 1 .. 100; 

   OBJ1,  
   OBJ2,  
   OBJ3,  
   AVG  : ONE_TO_100;  
begin
   OBJ1 := 70;
   OBJ2 := 70;
   OBJ3 := 70;
   AVG := OBJ1+OBJ2+OBJ3/3;
end average;


Thanks in advance



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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:01 Simple program to find average of 3 numbers prashna
@ 2003-07-04  5:22 ` John R. Strohm
  2003-07-04  5:34   ` Cephus�
  2003-07-04  5:33 ` Robert I. Eachus
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 28+ messages in thread
From: John R. Strohm @ 2003-07-04  5:22 UTC (permalink / raw)


"prashna" <vashwath@rediffmail.com> wrote in message
news:d40d7104.0307032101.94d27f2@posting.google.com...
> Hi friends,
>
> What is wrong in the following program which is giving constraint error?
>
> procedure average is
>    type ONE_TO_100 is range 1 .. 100;
>
>    OBJ1,
>    OBJ2,
>    OBJ3,
>    AVG  : ONE_TO_100;
> begin
>    OBJ1 := 70;
>    OBJ2 := 70;
>    OBJ3 := 70;
>    AVG := OBJ1+OBJ2+OBJ3/3;

     -- This line doesn't do what you think it does.
     -- Ask your TA to explain operator precedence to you in detail.

> end average;
>
>
> Thanks in advance





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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:01 Simple program to find average of 3 numbers prashna
  2003-07-04  5:22 ` John R. Strohm
@ 2003-07-04  5:33 ` Robert I. Eachus
  2003-07-04  8:37   ` Stuart Palin
  2003-07-04  5:39 ` tmoran
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 28+ messages in thread
From: Robert I. Eachus @ 2003-07-04  5:33 UTC (permalink / raw)


prashna wrote:
 > Hi friends,
 >
 > What is wrong in the following program which is giving constraint
 > error?
 >
 > procedure average is type ONE_TO_100 is range 1 .. 100;
 >
 > OBJ1, OBJ2, OBJ3, AVG  : ONE_TO_100; begin OBJ1 := 70; OBJ2 := 70;
 > OBJ3 := 70; AVG := OBJ1+OBJ2+OBJ3/3; end average;

I guess the right answer is that nothing is wrong with it, if you
want to be sure that you will get Constraint_Error.  As written, the 
code is required to raise Constraint_Error.

Oh, and then I could talk about your formatting, and identifier style. 
But I will address those by example.  Try:

procedure Average is
   subtype One_to_100 is Integer range 1 .. 100;
   Obj_1, Obj_2, Obj_3: One_to_100 := 70;
   Avg: One_to_100;
begin
   Avg := (Obj_1+Obj_2+Obj_3)/3;
   -- I assume you really wanted the average, rather than 163.
end Average;

-- 

                                                   Robert I. Eachus

�In an ally, considerations of house, clan, planet, race are
insignificant beside two prime questions, which are: 1. Can he shoot? 2.
Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and
Steve Miller.




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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:22 ` John R. Strohm
@ 2003-07-04  5:34   ` Cephus�
  2003-07-04  9:54     ` Tarjei T. Jensen
  0 siblings, 1 reply; 28+ messages in thread
From: Cephus� @ 2003-07-04  5:34 UTC (permalink / raw)




John R. Strohm wrote:
> "prashna" <vashwath@rediffmail.com> wrote in message
> news:d40d7104.0307032101.94d27f2@posting.google.com...
>> Hi friends,
>>
>> What is wrong in the following program which is giving constraint
>> error?
>>
>> procedure average is
>>    SUBtype ONE_TO_100 is range 1 .. 100;
>>
>>    OBJ1,
>>    OBJ2,
>>    OBJ3,
>>    AVG  : ONE_TO_100;
>> begin
>>    OBJ1 := 70;
>>    OBJ2 := 70;
>>    OBJ3 := 70;
>>    AVG := (OBJ1+OBJ2+OBJ3)/3;
>
>      -- This line doesn't do what you think it does.
>      -- Ask your TA to explain operator precedence to you in detail.
>
>> end average;
>>
>>
>> Thanks in advance

This is what it should be...


Beau





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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:01 Simple program to find average of 3 numbers prashna
  2003-07-04  5:22 ` John R. Strohm
  2003-07-04  5:33 ` Robert I. Eachus
@ 2003-07-04  5:39 ` tmoran
  2003-07-04  9:28   ` prashna
  2003-07-05 14:39 ` Marqmc5
  2003-07-06  3:47 ` g_ak
  4 siblings, 1 reply; 28+ messages in thread
From: tmoran @ 2003-07-04  5:39 UTC (permalink / raw)


>What is wrong in the following program which is giving constraint error?
 70+70+70/3= 163 > 100
Have a restorative weekend. ;)



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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:33 ` Robert I. Eachus
@ 2003-07-04  8:37   ` Stuart Palin
  2003-07-05 10:06     ` Preben Randhol
  0 siblings, 1 reply; 28+ messages in thread
From: Stuart Palin @ 2003-07-04  8:37 UTC (permalink / raw)


"Robert I. Eachus" wrote:
> 
> prashna wrote:
>  > Hi friends,
>  >
>  > What is wrong in the following program which is giving constraint
>  > error?
>  >
>  > procedure average is type ONE_TO_100 is range 1 .. 100;
>  >
>  > OBJ1, OBJ2, OBJ3, AVG  : ONE_TO_100; begin OBJ1 := 70; OBJ2 := 70;
>  > OBJ3 := 70; AVG := OBJ1+OBJ2+OBJ3/3; end average;
> 
<snip>
> 
> Oh, and then I could talk about your formatting, and identifier style.
> But I will address those by example.  Try:
> 
> procedure Average is
>    subtype One_to_100 is Integer range 1 .. 100;
>    Obj_1, Obj_2, Obj_3: One_to_100 := 70;
>    Avg: One_to_100;
> begin
>    Avg := (Obj_1+Obj_2+Obj_3)/3;
>    -- I assume you really wanted the average, rather than 163.
> end Average;

You might also want to consider what values the intermediate
calculation Obj_1+Obj_2+Obj_3 can take.  In this instance
because your type is constrained to a number which should be
well within the bounds of integer you would not experience a
problem.

Questions to ask yourself (and seek answers to):
a) What if the bounds of the type were larger?
b) How might it be possible to detect a potential constraint
error at compile time rather than during execution?

--
Stuart Palin



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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:39 ` tmoran
@ 2003-07-04  9:28   ` prashna
  2003-07-04 11:02     ` Stuart Palin
                       ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: prashna @ 2003-07-04  9:28 UTC (permalink / raw)


tmoran@acm.org wrote in message news:<uq8Na.7195$NW6.4891@rwcrnsc51.ops.asp.att.net>...
> >What is wrong in the following program which is giving constraint error?
>  70+70+70/3= 163 > 100
> Have a restorative weekend. ;)

O.K, I have changed line 12 to  AVG := (OBJ1+OBJ2+OBJ3)/3;
But still it giving constraint error!!! :((



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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:34   ` Cephus�
@ 2003-07-04  9:54     ` Tarjei T. Jensen
  2003-07-05 17:49       ` Cephus�
  0 siblings, 1 reply; 28+ messages in thread
From: Tarjei T. Jensen @ 2003-07-04  9:54 UTC (permalink / raw)


"Cephus�" wrote:
> This is what it should be...

He will not learn much if there is no effort in the learning.

You might think you have been helpful, but most likely you have done the
person a disservice.

greetings,





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

* Re: Simple program to find average of 3 numbers
  2003-07-04  9:28   ` prashna
@ 2003-07-04 11:02     ` Stuart Palin
  2003-07-04 16:20     ` Pascal Obry
       [not found]     ` <1e3ht-ig4.ln1@beastie.ix.netcom.com>
  2 siblings, 0 replies; 28+ messages in thread
From: Stuart Palin @ 2003-07-04 11:02 UTC (permalink / raw)


prashna wrote:

> O.K, I have changed line 12 to  AVG := (OBJ1+OBJ2+OBJ3)/3;
> But still it giving constraint error!!! :((

Having another look at your original posting, notice that
there is a difference between the way you have declared your
type and the way it is declared in Robert Eachus' example.

Do you get the exception with Robert's example?
If not what might be the underlying difference?

Think again about the points I raised earlier:

> You might also want to consider what values the intermediate
> calculation Obj_1+Obj_2+Obj_3 can take.

OK, the second sentence really applies to Robert's
example...
> In this instance because your type is constrained to a
> number which should be well within the bounds of integer
> you would not experience a problem.

What context might the expression be evaluated in in your
example?

(Think about 'base types' try ranges of 1..42 and 1..43
[with suitable initial values].  What interesting number
lies between 3*42 and 3*43?)

How might it be possible to detect a potential constraint
error at compile time rather than during execution?

--
Stuart Palin



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

* Re: Simple program to find average of 3 numbers
  2003-07-04  9:28   ` prashna
  2003-07-04 11:02     ` Stuart Palin
@ 2003-07-04 16:20     ` Pascal Obry
  2003-07-05  1:25       ` Robert I. Eachus
       [not found]     ` <1e3ht-ig4.ln1@beastie.ix.netcom.com>
  2 siblings, 1 reply; 28+ messages in thread
From: Pascal Obry @ 2003-07-04 16:20 UTC (permalink / raw)



vashwath@rediffmail.com (prashna) writes:

> O.K, I have changed line 12 to  AVG := (OBJ1+OBJ2+OBJ3)/3;
> But still it giving constraint error!!! :((

This is just not possible or it is a compiler bug (quite unlikely though). Be
sure to recompile and link your program.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|         http://perso.wanadoo.fr/pascal.obry
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



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

* Re: Simple program to find average of 3 numbers
       [not found]     ` <1e3ht-ig4.ln1@beastie.ix.netcom.com>
@ 2003-07-04 21:17       ` Jeffrey Creem
  2003-07-05  5:07         ` Anders Wirzenius
  0 siblings, 1 reply; 28+ messages in thread
From: Jeffrey Creem @ 2003-07-04 21:17 UTC (permalink / raw)


Remeber everyone. -gnato is your friend.


GNAT by default does not run with integer overflow checks enabled.

try again

gnatmake -f -gnato avg

Gets Constraint_Error on GNAT 3.15p under windows XP.



"Dennis Lee Bieber" <wlfraed@ix.netcom.com> wrote in message
news:1e3ht-ig4.ln1@beastie.ix.netcom.com...
> prashna fed this fish to the penguins on Friday 04 July 2003 02:28 am:
>
> >
> > O.K, I have changed line 12 to  AVG := (OBJ1+OBJ2+OBJ3)/3;
> > But still it giving constraint error!!! :((
>
>         What compiler, and what OS?
>
>
> ---- avg.adb, using GNAT 3.15p, Mandrake Linux 8.2
>
> procedure avg is
>
>         type ONE_TO_100 is range 1..100;
>
>         Obj1, Obj2, Obj3 : ONE_TO_100;
>         Avg : ONE_TO_100;
>
> begin
>         Obj1 := 70;
>         Obj2 := 70;
>         Obj3 := 70;
>
>         Avg := (Obj1 + Obj2 + Obj3) / 3;
> end avg;
>
> ----
> [wulfraed@beastie ada]$ gnatmake avg
> gcc -c avg.adb
> gnatbind -x avg.ali
> gnatlink avg.ali
>
> [wulfraed@beastie ada]$ ./avg
>
>         No error (no output either, but you didn't have any shown...
>
> -- 
>  > ============================================================== <
>  >   wlfraed@ix.netcom.com  | Wulfraed  Dennis Lee Bieber  KD6MOG <
>  >      wulfraed@dm.net     |       Bestiaria Support Staff       <
>  > ============================================================== <
>  >        Bestiaria Home Page: http://www.beastie.dm.net/         <
>  >            Home Page: http://www.dm.net/~wulfraed/             <
>





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

* Re: Simple program to find average of 3 numbers
  2003-07-04 16:20     ` Pascal Obry
@ 2003-07-05  1:25       ` Robert I. Eachus
  0 siblings, 0 replies; 28+ messages in thread
From: Robert I. Eachus @ 2003-07-05  1:25 UTC (permalink / raw)


Pascal Obry wrote:
> vashwath@rediffmail.com (prashna) writes:
> 
> 
>>O.K, I have changed line 12 to  AVG := (OBJ1+OBJ2+OBJ3)/3;
>>But still it giving constraint error!!! :((
> 
> This is just not possible or it is a compiler bug (quite unlikely though). Be
> sure to recompile and link your program.

Oh, no, it is very possible.  It depend on the actual base type chosen 
by the compiler.  If that type is an 8-bit signed type, then since 210 > 
127 you get Constraint_Error.  That is why I changed the type 
declaration to a subtype declaration in my rewrite.

-- 

                                                        Robert I. Eachus

�In an ally, considerations of house, clan, planet, race are 
insignificant beside two prime questions, which are: 1. Can he shoot? 2. 
Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and 
Steve Miller.




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

* Re: Simple program to find average of 3 numbers
  2003-07-04 21:17       ` Jeffrey Creem
@ 2003-07-05  5:07         ` Anders Wirzenius
  0 siblings, 0 replies; 28+ messages in thread
From: Anders Wirzenius @ 2003-07-05  5:07 UTC (permalink / raw)



"Jeffrey Creem" <jeff@thecreems.com> wrote in message
news:g9mNa.36436$926.3783@sccrnsc03...
> gnatmake -f -gnato avg
>
> Gets Constraint_Error on GNAT 3.15p under windows XP.

So the question arises: did the OP specify -gnato? If no, there might
be something wrong with his compiler :-)

Anders




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

* Re: Simple program to find average of 3 numbers
  2003-07-04  8:37   ` Stuart Palin
@ 2003-07-05 10:06     ` Preben Randhol
  0 siblings, 0 replies; 28+ messages in thread
From: Preben Randhol @ 2003-07-05 10:06 UTC (permalink / raw)


Stuart Palin wrote:
> "Robert I. Eachus" wrote:
>> 
>> prashna wrote:
>>  > Hi friends,
>>  >
>>  > What is wrong in the following program which is giving constraint
>>  > error?
>>  >
>>  > procedure average is type ONE_TO_100 is range 1 .. 100;
>>  >
>>  > OBJ1, OBJ2, OBJ3, AVG  : ONE_TO_100; begin OBJ1 := 70; OBJ2 := 70;
>>  > OBJ3 := 70; AVG := OBJ1+OBJ2+OBJ3/3; end average;
>> 
><snip>
>> 
>> Oh, and then I could talk about your formatting, and identifier style.
>> But I will address those by example.  Try:
>> 
>> procedure Average is
>>    subtype One_to_100 is Integer range 1 .. 100;
>>    Obj_1, Obj_2, Obj_3: One_to_100 := 70;
>>    Avg: One_to_100;
>> begin
>>    Avg := (Obj_1+Obj_2+Obj_3)/3;
>>    -- I assume you really wanted the average, rather than 163.
>> end Average;
> 
> You might also want to consider what values the intermediate
> calculation Obj_1+Obj_2+Obj_3 can take.  In this instance
> because your type is constrained to a number which should be
> well within the bounds of integer you would not experience a
> problem.

Which instance are you refering to? Mr Eachus' subtype or OP's type
declaration? If you do the calculations above aren't the
intermediate variable of the same type (ONE_TO_100) with same contraint
unless you use a subtype to Integer like Mr Eachus?

-- 
Ada95 is good for you.
http://www.crystalcode.com/codemage/MainMenu/Coding/Ada/IntroducingAda.php



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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:01 Simple program to find average of 3 numbers prashna
                   ` (2 preceding siblings ...)
  2003-07-04  5:39 ` tmoran
@ 2003-07-05 14:39 ` Marqmc5
  2003-07-06  3:47 ` g_ak
  4 siblings, 0 replies; 28+ messages in thread
From: Marqmc5 @ 2003-07-05 14:39 UTC (permalink / raw)


The sum of OBJ1 + OBJ2 +OBJ3 is 210, which is a bit over 100, out of range of
your type-cast.



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

* Re: Simple program to find average of 3 numbers
  2003-07-04  9:54     ` Tarjei T. Jensen
@ 2003-07-05 17:49       ` Cephus�
  0 siblings, 0 replies; 28+ messages in thread
From: Cephus� @ 2003-07-05 17:49 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 441 bytes --]



Tarjei T. Jensen wrote:
> "Cephus�" wrote:
>> This is what it should be...
>
> He will not learn much if there is no effort in the learning.
>
> You might think you have been helpful, but most likely you have done
> the person a disservice.
>
> greetings,

well if he can't see that then he/she really won't be hurt by my help...
THAT IS SOMETHING IN ALGEBRA YOU LEARN IN ELEMENTARY! he just probably
forgot that.... geezzz...

Beau





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

* Re: Simple program to find average of 3 numbers
  2003-07-04  5:01 Simple program to find average of 3 numbers prashna
                   ` (3 preceding siblings ...)
  2003-07-05 14:39 ` Marqmc5
@ 2003-07-06  3:47 ` g_ak
  2003-07-08  5:06   ` prashna
  4 siblings, 1 reply; 28+ messages in thread
From: g_ak @ 2003-07-06  3:47 UTC (permalink / raw)


prashna wrote:
> Hi friends,
> 
> What is wrong in the following program which is giving constraint error?
> 
> procedure average is 
>    type ONE_TO_100 is range 1 .. 100; 
> 
>    OBJ1,  
>    OBJ2,  
>    OBJ3,  
>    AVG  : ONE_TO_100;  
> begin
>    OBJ1 := 70;
>    OBJ2 := 70;
>    OBJ3 := 70;
>    AVG := OBJ1+OBJ2+OBJ3/3;
> end average;
> 
> 
> Thanks in advance


prashna,

you shoud declare your type "one_to_100" differently...



this should work better:
-------------------------------------------------------
procedure Average is

    type One_To_100 is new Integer range 1 .. 100;

    Obj1,
    Obj2,
    Obj3,
    Avg  : One_To_100;

begin
    Obj1 := 70;
    Obj2 := 70;
    Obj3 := 70;
    AVG := (OBJ1+OBJ2+OBJ3)/3;
end Average;

-------------------------------------------------------

you will get a constraint error only when the sum of OBJ1+OBJ2+OBJ3 will
reach a number higher than the highest permited  value in the Integer 
type (2**15-1 if iremember well)

gilles




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

* Re: Simple program to find average of 3 numbers
  2003-07-06  3:47 ` g_ak
@ 2003-07-08  5:06   ` prashna
  2003-07-09 15:25     ` Matthew Heaney
  0 siblings, 1 reply; 28+ messages in thread
From: prashna @ 2003-07-08  5:06 UTC (permalink / raw)


> you shoud declare your type "one_to_100" differently... 
> this should work better:
> -------------------------------------------------------
> procedure Average is
> 
>     type One_To_100 is new Integer range 1 .. 100;
> 
>     Obj1,
>     Obj2,
>     Obj3,
>     Avg  : One_To_100;
> 
> begin
>     Obj1 := 70;
>     Obj2 := 70;
>     Obj3 := 70;
>     AVG := (OBJ1+OBJ2+OBJ3)/3;
> end Average;
> 
> -------------------------------------------------------
> 
> you will get a constraint error only when the sum of OBJ1+OBJ2+OBJ3 will
> reach a number higher than the highest permited  value in the Integer 
> type (2**15-1 if iremember well)
> 
> gilles


Thanks every one for the replies.

Among these two type declarations which is better one?In my opinion
declaring a type as derived type of another type (integer in this
case) is better one because the intermediate results of arithmetic
operations will be stored as integer type or Is there any advantage of
declaring a type as just a values within certain range (ex:type
ONE_TO_100 is range 1 .. 100;)?

Thanks



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

* Re: Simple program to find average of 3 numbers
@ 2003-07-09  6:24 christoph.grein
  0 siblings, 0 replies; 28+ messages in thread
From: christoph.grein @ 2003-07-09  6:24 UTC (permalink / raw)
  To: comp.lang.ada

type T1 is range a .. b;
type T2 is new T0 range a .. b;

For T1, you leave the choice of base type to the compiler (T1'Base is 
implementation defined - it will normally be the smallest predefined type having 
a matching range).
For T2, T2'Base has the same constraints as T0'Base.



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

* Re: Simple program to find average of 3 numbers
  2003-07-08  5:06   ` prashna
@ 2003-07-09 15:25     ` Matthew Heaney
  2003-07-09 21:38       ` Robert I. Eachus
  2003-07-10  4:55       ` Simon Wright
  0 siblings, 2 replies; 28+ messages in thread
From: Matthew Heaney @ 2003-07-09 15:25 UTC (permalink / raw)


vashwath@rediffmail.com (prashna) wrote in message news:<d40d7104.0307072106.1ad3b378@posting.google.com>...
> > you shoud declare your type "one_to_100" differently... 
> > this should work better:
> > -------------------------------------------------------
> > procedure Average is
> > 
> >     type One_To_100 is new Integer range 1 .. 100;
> > 
> >     Obj1,
> >     Obj2,
> >     Obj3,
> >     Avg  : One_To_100;
> > 
> > begin
> >     Obj1 := 70;
> >     Obj2 := 70;
> >     Obj3 := 70;
> >     AVG := (OBJ1+OBJ2+OBJ3)/3;
> > end Average;
> > 
> > -------------------------------------------------------
> > 
> > you will get a constraint error only when the sum of OBJ1+OBJ2+OBJ3 will
> > reach a number higher than the highest permited  value in the Integer 
> > type (2**15-1 if iremember well)
> > 
> > gilles
> 
> 
> Thanks every one for the replies.
> 
> Among these two type declarations which is better one?In my opinion
> declaring a type as derived type of another type (integer in this
> case) is better one because the intermediate results of arithmetic
> operations will be stored as integer type or Is there any advantage of
> declaring a type as just a values within certain range (ex:type
> ONE_TO_100 is range 1 .. 100;)?

This is actually an important question, because it highlights some
subtleties in the Ada type system.

In the type declaration

  type T is range 1 .. 100;

the type T is actually a subtype of the underlying type.  The
underlying type has no name, but we can refer to it as T'Base.  The
name T is its "first named subtype."

The type has a range that includes all the values in the first named
subtype T, and is symmetric around 0.

So what we really have is this:

  type T'Base is range -100 .. 100;
  subtype T is T_Base range 1 .. 100;

The predefined operations for an integer type are declared this way:

  function "+" (L, R : T'Base) return T'Base;

Note that the types in the function declaration are T'Base, not T.  

The addition is computed using the range of values in the base type. 
In particular, this means that the programmer is responsible for
ensuring that the base range of the type includes a wide enough range
to compute intermediate values during expression evalution.

The intermediate sum in your example has a value 3 * 70 = 210, which
is outside the base range of the type, which only includes values up
to 100.

This means that your type declaration is wrong.  The intermediate
value causes integer overflow, because the value is outside the base
range of the type.

What you need to do is declare your type this way:

declare
   type T_Base is range -300 .. 300;
   subtype T is T_Base range 1 .. 100;

   X, Y, Z : constant T := 70;
   Sum : constant T := (X + Y + Z) / 3;
begin

The executes fine using gnat 3.15p on WinXP.

The moral of the story is that you have to you have to take
responsibility for ensuring that you have a type that is large enough
for intermediate values.  So must analyze your algorithm to determine
what the max value is.

You can simplify things by declaring your base type as deriving from
type Integer:

declare
  type T_Base is new Integer;
  subtype T is T_Base range 1 .. 100;
...
begin

This gives you a range that is "natural" for your machine.  However,
it's still up to you to perform a minimal boundary analysis of your
algorithm to ensure that intermediate values can be safely computed. 
This is true when programming in any language.  The difference when
programming in Ada is that Ada lets you know when you made a mistake.

As was pointed out, when using gnat you should always specify the
-gnato option, to enable integer overflow checks.  (However, I did get
the overflow check without specifying that switch, so perhaps
something has changed in the 3.15p release of gnat.)

The type declaration in your example looks like this:

  type T is new Integer range 1 .. 100;

However, I'm not sure whether it corresponds to the declarations

  type T_Base is new Integer;
  subtype T is T_Base range 1 .. 100;

or to the declarations:
 
   type T_Base is range -100 .. 100;
   subtype T is T_Base range 1 .. 100;

It executes fine when I run it, so it seems to correspond to the
former pair.



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

* Re: Simple program to find average of 3 numbers
  2003-07-09 15:25     ` Matthew Heaney
@ 2003-07-09 21:38       ` Robert I. Eachus
  2003-07-10 13:52         ` Matthew Heaney
  2003-07-11 21:50         ` Robert A Duff
  2003-07-10  4:55       ` Simon Wright
  1 sibling, 2 replies; 28+ messages in thread
From: Robert I. Eachus @ 2003-07-09 21:38 UTC (permalink / raw)


Matthew Heaney wrote:

 > This is actually an important question, because it highlights some
 > subtleties in the Ada type system.
 >
 > In the type declaration
 >
 > type T is range 1 .. 100;
 >
 > the type T is actually a subtype of the underlying type.  The
 > underlying type has no name, but we can refer to it as T'Base.  The
 > name T is its "first named subtype."
 >
 > The type has a range that includes all the values in the first named
 > subtype T, and is symmetric around 0.

AT LEAST all the values in the range, and is symmetric around zero with
a possible extra negative value.  (Can you tell I am a language lawyer
by nature?)

If you want to ensure a precise range for the base type, specify the
size as well:

type Tiny_Int is range -128..127;
for Tiny_Int'Size use 8;

 > The addition is computed using the range of values in the base type.

No,  "The predefined operations on integer types either yield the
mathematically correct result or raise the exception Constraint_Error."
RM 4.5(10)  Arithmetic operations are not required to raise
Constraint_Error if the value of the expression as a whole is in range,
because that would prevent many useful optimizations.  (However, the
sentence above was moved from 11.6 in Ada 83 to 4.5.  But the meaning
hasn't changed.)  For example, if you write Z := 2*X + 2*Y; the compiler
is allowed to generate code for 2*(X+Y).  This will only generate an
exception in cases where 2*X + 2*Y does, but there are some cases where
you get the correct mathmatical result with the optimized expression,
and a Constraint_Error with the unoptimized version.

 > In particular, this means that the programmer is responsible for
 > ensuring that the base range of the type includes a wide enough range
 >  to compute intermediate values during expression evalution...

Correct.

 > The type declaration in your example looks like this:
 >
 > type T is new Integer range 1 .. 100;
 >
 > However, I'm not sure whether it corresponds to the declarations
 >
 > type T_Base is new Integer; subtype T is T_Base range 1 .. 100;
 >
 > or to the declarations:
 >
 > type T_Base is range -100 .. 100; subtype T is T_Base range 1 .. 100;
 >
 >
 > It executes fine when I run it, so it seems to correspond to the
 > former pair.

It corresponds to:

     subtype T is <implementation defined integer type> range 1..100;

except that one thing we learned from Ada 83 is that such "helpful"
analogies are always wrong. ;-)  Which is why you won't find any in the
Ada 95 RM.

If you want to find out what the compiler will do you can write a short
program to find out:
--------------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
procedure Num_Types is

   type One_To_100 is range 1..100;

   type Eight_Bits is range 1..100;
   for Eight_Bits'Size use 8;

begin

New_Line;
Put_Line(" Type One_To_100 is " &
Integer'Image(Integer(One_To_100'Base'First))
   & ".." & Integer'Image(Integer(One_To_100'Base'Last)) & '.');
Put_Line(" Type Eight_Bits is " &
Integer'Image(Integer(Eight_Bits'Base'First))
   & ".." & Integer'Image(Integer(Eight_Bits'Base'Last)) & '.');
New_Line;

end Num_Types;
------------------------------------------------------------------------
with GNAT:

num_types

  Type One_To_100 is -128.. 127.
  Type Eight_Bits is -128.. 127.

If I seem to be picking on Matt, I'm not.  His answer was close enough
to right that I wanted to be sure to correct the spots where it wasn't
perfect.  This is an area where the changes in the rules between Ada 83 
and Ada 95 can be confusing, even though for the most part they say 
exactly the same thing.  (The differences are very subtle, involving 
what you can count on being correct after Constraint_Error is raised.)

-- 

                                              Robert I. Eachus

�In an ally, considerations of house, clan, planet, race are
insignificant beside two prime questions, which are: 1. Can he shoot? 2.
Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and
Steve Miller.




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

* Re: Simple program to find average of 3 numbers
  2003-07-09 15:25     ` Matthew Heaney
  2003-07-09 21:38       ` Robert I. Eachus
@ 2003-07-10  4:55       ` Simon Wright
  1 sibling, 0 replies; 28+ messages in thread
From: Simon Wright @ 2003-07-10  4:55 UTC (permalink / raw)


mheaney@on2.com (Matthew Heaney) writes:

> As was pointed out, when using gnat you should always specify the
> -gnato option, to enable integer overflow checks.  (However, I did
> get the overflow check without specifying that switch, so perhaps
> something has changed in the 3.15p release of gnat.)

I think the overflow checks are for overflow in the base type, so for
T_Base is new Integer you'ld have to do something like Integer'Last +
1.



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

* Re: Simple program to find average of 3 numbers
  2003-07-09 21:38       ` Robert I. Eachus
@ 2003-07-10 13:52         ` Matthew Heaney
  2003-07-10 15:46           ` Robert I. Eachus
  2003-07-11 21:54           ` Robert A Duff
  2003-07-11 21:50         ` Robert A Duff
  1 sibling, 2 replies; 28+ messages in thread
From: Matthew Heaney @ 2003-07-10 13:52 UTC (permalink / raw)


"Robert I. Eachus" <rieachus@attbi.com> wrote in message news:<3F0C8B45.2080108@attbi.com>...
> Matthew Heaney wrote:
> 
>  > The type declaration in your example looks like this:
>  >
>  > type T is new Integer range 1 .. 100;
>  >
>  > However, I'm not sure whether it corresponds to the declarations
>  >
>  > type T_Base is new Integer; subtype T is T_Base range 1 .. 100;
>  >
>  > or to the declarations:
>  >
>  > type T_Base is range -100 .. 100; subtype T is T_Base range 1 .. 100;
>  >
>  >
>  > It executes fine when I run it, so it seems to correspond to the
>  > former pair.
> 
> It corresponds to:
> 
>      subtype T is <implementation defined integer type> range 1..100;
> 
> except that one thing we learned from Ada 83 is that such "helpful"
> analogies are always wrong. ;-)  Which is why you won't find any in the
> Ada 95 RM.

But the question is: what is the base range of the "implementation
defined integer type"?  For declarations of this style:

   type T is new Integer range 1 .. 100;

can was assume that the base range of the type includes all the values
in Integer'Base, or only the values in the range -100 .. 100?

With respect to the base range of the type, how do the declarations

   type T is new Integer range 1 .. 100;
   type T is range 1 .. 100;

differ from one another?



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

* Re: Simple program to find average of 3 numbers
  2003-07-10 13:52         ` Matthew Heaney
@ 2003-07-10 15:46           ` Robert I. Eachus
  2003-07-11  0:56             ` Randy Brukardt
  2003-07-11 21:54           ` Robert A Duff
  1 sibling, 1 reply; 28+ messages in thread
From: Robert I. Eachus @ 2003-07-10 15:46 UTC (permalink / raw)


Matthew Heaney wrote:

> But the question is: what is the base range of the "implementation
> defined integer type"?  For declarations of this style:
> 
>    type T is new Integer range 1 .. 100;
> 
> can was assume that the base range of the type includes all the values
> in Integer'Base, or only the values in the range -100 .. 100?

In that case T'Base has the same range as Integer'Base.

> With respect to the base range of the type, how do the declarations
> 
>    type T is new Integer range 1 .. 100;
>    type T is range 1 .. 100;
> 
> differ from one another?

Look at the output from the program I provided.  In the first case, the 
base type has the same characteristics as Integer'Base.  In the second 
example, look at the results of the program I ran.  The compiler can 
choose any predefined integer type for the base type.  In this case, 
GNAT choose one with a range -128..127.
-- 

                                                        Robert I. Eachus

�In an ally, considerations of house, clan, planet, race are 
insignificant beside two prime questions, which are: 1. Can he shoot? 2. 
Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and 
Steve Miller.




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

* Re: Simple program to find average of 3 numbers
  2003-07-10 15:46           ` Robert I. Eachus
@ 2003-07-11  0:56             ` Randy Brukardt
  0 siblings, 0 replies; 28+ messages in thread
From: Randy Brukardt @ 2003-07-11  0:56 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1620 bytes --]

> Matthew Heaney wrote:
> > With respect to the base range of the type, how do the declarations
> >
> >    type T is new Integer range 1 .. 100;
> >    type T is range 1 .. 100;
> >
> > differ from one another?

For the first, the base type is derived from Integer'Base. So T'Base'First =
Integer'Base'First.

OTOH, all we know about the second T is that T'First <= -100, and T'Last >=
100. (Generally, it is some power of two). Thus, the second gives more power
to the compiler, and thus is preferred.

For instance, Janus/Ada has historically used Integer'Size = 16 (that kept
all of our compilers compatible -- probably a bad choice, but it is
impossible to change without breaking a lot of user code).
    type T1 is Integer range 0 .. 100_000;
       -- Raises Constraint_Error on most versions of Janus/Ada; will work
on GNAT, etc.
    type T2 is range 0 .. 100_000;
       -- Works fine on all modern versions of Janus/Ada.

                        Randy.




> Look at the output from the program I provided.  In the first case, the
> base type has the same characteristics as Integer'Base.  In the second
> example, look at the results of the program I ran.  The compiler can
> choose any predefined integer type for the base type.  In this case,
> GNAT choose one with a range -128..127.
> --
>
>                                                         Robert I. Eachus
>
> �In an ally, considerations of house, clan, planet, race are
> insignificant beside two prime questions, which are: 1. Can he shoot? 2.
> Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and
> Steve Miller.
>





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

* Re: Simple program to find average of 3 numbers
  2003-07-09 21:38       ` Robert I. Eachus
  2003-07-10 13:52         ` Matthew Heaney
@ 2003-07-11 21:50         ` Robert A Duff
  2003-07-11 23:32           ` Robert I. Eachus
  1 sibling, 1 reply; 28+ messages in thread
From: Robert A Duff @ 2003-07-11 21:50 UTC (permalink / raw)


"Robert I. Eachus" <rieachus@attbi.com> writes:

> If you want to ensure a precise range for the base type, specify the
> size as well:
> 
> type Tiny_Int is range -128..127;
> for Tiny_Int'Size use 8;

The Size clause has no effect on the base range.

- Bob



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

* Re: Simple program to find average of 3 numbers
  2003-07-10 13:52         ` Matthew Heaney
  2003-07-10 15:46           ` Robert I. Eachus
@ 2003-07-11 21:54           ` Robert A Duff
  1 sibling, 0 replies; 28+ messages in thread
From: Robert A Duff @ 2003-07-11 21:54 UTC (permalink / raw)


mheaney@on2.com (Matthew Heaney) writes:

> But the question is: what is the base range of the "implementation
> defined integer type"?  For declarations of this style:
> 
>    type T is new Integer range 1 .. 100;
> 
> can was assume that the base range of the type includes all the values
> in Integer'Base,

Yes.

>... or only the values in the range -100 .. 100?
> 
> With respect to the base range of the type, how do the declarations
> 
>    type T is new Integer range 1 .. 100;

Base range is at least Integer'First..Integer'Last,
which is at least the 16-bit range.

>    type T is range 1 .. 100;

Base range is at least -100..100.

> differ from one another?

The above is according to the RM.  These are minimal ranges.  Compilers
can choose wider base ranges, and for any particular expression, the
compiler is always allowed to get the right answer even if it is outside
the base range.  Base ranges give you a minimal range for intermediate
results, guaranteed not to overflow.

- Bob



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

* Re: Simple program to find average of 3 numbers
  2003-07-11 21:50         ` Robert A Duff
@ 2003-07-11 23:32           ` Robert I. Eachus
  0 siblings, 0 replies; 28+ messages in thread
From: Robert I. Eachus @ 2003-07-11 23:32 UTC (permalink / raw)


Robert A Duff wrote:

> The Size clause has no effect on the base range.

 From a language lawyer point of view, I guess that is true, just not 
all that helpful.  In Ada 83 some compilers did allow a 'Size clause to 
influence representations.  It was the easiest way to deal with the 
"junk" for Character'Size use 7; in (Ada 83) package Standard.  And as 
long as you were dealing with that to pass the ACVC tests, might as well 
actually try to do something useful with it.  Of course, on the 
compilers that cared, very few implemented all the possible integer base 
types.  (Ada/SIL did support Integer_2 through Integer_16 plus (32-bit) 
Long_Integer as potential base types, but would choose Integer (16-bits) 
for all smaller types absent a size clause.

-- 

                                                        Robert I. Eachus

�In an ally, considerations of house, clan, planet, race are 
insignificant beside two prime questions, which are: 1. Can he shoot? 2. 
Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and 
Steve Miller.




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

end of thread, other threads:[~2003-07-11 23:32 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-04  5:01 Simple program to find average of 3 numbers prashna
2003-07-04  5:22 ` John R. Strohm
2003-07-04  5:34   ` Cephus�
2003-07-04  9:54     ` Tarjei T. Jensen
2003-07-05 17:49       ` Cephus�
2003-07-04  5:33 ` Robert I. Eachus
2003-07-04  8:37   ` Stuart Palin
2003-07-05 10:06     ` Preben Randhol
2003-07-04  5:39 ` tmoran
2003-07-04  9:28   ` prashna
2003-07-04 11:02     ` Stuart Palin
2003-07-04 16:20     ` Pascal Obry
2003-07-05  1:25       ` Robert I. Eachus
     [not found]     ` <1e3ht-ig4.ln1@beastie.ix.netcom.com>
2003-07-04 21:17       ` Jeffrey Creem
2003-07-05  5:07         ` Anders Wirzenius
2003-07-05 14:39 ` Marqmc5
2003-07-06  3:47 ` g_ak
2003-07-08  5:06   ` prashna
2003-07-09 15:25     ` Matthew Heaney
2003-07-09 21:38       ` Robert I. Eachus
2003-07-10 13:52         ` Matthew Heaney
2003-07-10 15:46           ` Robert I. Eachus
2003-07-11  0:56             ` Randy Brukardt
2003-07-11 21:54           ` Robert A Duff
2003-07-11 21:50         ` Robert A Duff
2003-07-11 23:32           ` Robert I. Eachus
2003-07-10  4:55       ` Simon Wright
  -- strict thread matches above, loose matches on Subject: below --
2003-07-09  6:24 christoph.grein

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