From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,30e0ceaf4e6be70c X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-07-09 08:25:45 PST Path: archiver1.google.com!postnews1.google.com!not-for-mail From: mheaney@on2.com (Matthew Heaney) Newsgroups: comp.lang.ada Subject: Re: Simple program to find average of 3 numbers Date: 9 Jul 2003 08:25:44 -0700 Organization: http://groups.google.com/ Message-ID: <1ec946d1.0307090725.73f5f200@posting.google.com> References: <6ZMNa.109291$0B.2183354@wagner.videotron.net> NNTP-Posting-Host: 66.162.65.162 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Trace: posting.google.com 1057764345 25244 127.0.0.1 (9 Jul 2003 15:25:45 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: 9 Jul 2003 15:25:45 GMT Xref: archiver1.google.com comp.lang.ada:40145 Date: 2003-07-09T15:25:45+00:00 List-Id: vashwath@rediffmail.com (prashna) wrote in message news:... > > 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.