rds@moss.ATT.COM (04/21/88)
How does one implement an unsigned integer in Ada and have a maximum value equal to 2**(number of bits) in any given implementation? Is this an oversight or does Ada really limit maximum integer values to 2**(# of bits MINUS ONE)-1. More verbosely put declaring type Pointer is range 0..(2**32)-1; for Pointer'SIZE use 32; is invalid for a 32 bit integer implementation because (2**32)-1 is not in the INTEGER'RANGE -(2**31)..(2**31)-1. How can I use the leftover bit? subtype Pointer is INTEGER range 0..(2**32)-1; for Pointer'SIZE use 32; is illegal because it is not a <first named subtype> LRM 13.1 (3) WHAT IS A FIRST NAMED SUBTYPE?? And can someone give an example? Any assistance will keep the hair in my head for another day (Ada problem).
stt@ada-uts (04/26/88)
Ada requires that all predefined integer types be symmetric about zero, excepting an extra negative value (LRM 3.5.4:7), and that all integer types be derived directly or indirectly from one of these. However, it would be permissible to define a LONG_INTEGER which is signed 64 bits, and then define a subtype of that which is unsigned 32 bits, and implement it using unsigned 32 bit representation in memory (though the arithmetic would still have to allow 64-bit intermediate results without NUMERIC_ERROR). Representation clauses are only allowed for "first named subtypes" (defined in LRM 13.1:3). The first named subtype is the subtype identified in a "type definition." The type is generally anonymous and unconstrained; the identifier specified designates a subtype. For example type My_Int is range 0..15; This is formally equivalent to (see LRM 3.5.4:5,6): type <anon> is new <predefined-int-type>; subtype My_Int is <anon> range 0..15; "My_Int" is therefore the "first named subtype." Allowing unsigned types in general has been proposed as a possible addition for the next revision of Ada, but beware that it would imply NUMERIC_ERROR if the arithmetic result goes negative, rather than just wrapping around, as most "C" programmers expect. Furthermore, there would have to be a rule for deciding which predefined type is selected for any given integer type definition with a non-negative range (the signed one or the unsigned one), since this would determine the legality of negative intermediate arithmetic results. Tucker Taft Intermetrics, Inc. Cambridge, MA 02138
garym@telesoft.UUCP (Gary Morris @flash) (04/27/88)
> From: ncar!noao!mcdsun!mcdchg!clyde!rds%moss.ATT.COM@AMES.ARC.NASA.GOV > Subject: unsigned integers in Ada > > How does one implement an unsigned integer in Ada and have a maximum > value equal to 2**(number of bits) in any given implementation? The LRM requires that predefined integer types be symmetrical around zero (LRM 3.5.4 (7)). It is illegal to provide an unsigned integer type in package standard. So the largest type provided on a 32 bit machine will normally be -(2**31)..(2**31)-1. That means that you can't declare a type that is range 0..(2**32)-1 unless the compiler supports a standard integer type large enough to contain that range (and it must be symmetrical around zero)! The following declaration would require 33 bit or larger (ie: 64 bit) integer defined in package standard in order for the compiler to accept it: type Unsigned_Long is range 0..(2**32)-1; -- 64 bit base type for Unsigned_Long'size use 32; -- packed in 32 bits The expressions using the Unsigned_Long would have to be evaluated using 64-bit arithmetic for intermediate results. Due to these restrictions, unsigned types in Ada are just a form of packing. The compiler is not allowed to perform unsigned operations on the type as you would in assembly making operations on such types less efficient. It would be interesting to hear why the language designers chose to restrict types this way. The following declaration is legal on most compilers because most support a integer type in package standard that is 32 bits. The operations are still done using the 32 bit base type that contains the positive range you want but must also be symmetrical around zero: type Unsigned_Word is range 0..(2**16)-1; -- 32 bit base type for Unsigned_Word'size use 16; -- packed in 16 bits > subtype Pointer is INTEGER range 0..(2**32)-1; > for Pointer'SIZE use 32; > > is illegal because it is not a <first named subtype> LRM 13.1 (3) > WHAT IS A FIRST NAMED SUBTYPE?? And can someone give an example? You can't change the representation of a subtype unless it is a first-named subtype since subtypes derive their representation from the base type. A <first named subtype> is a subtype declared by a type declaration where the base type is anonymous. For example: type T is range L .. R; -- example from LRM 3.5.4 (5) --GaryM P.S. Thanks go to JPD for explaining this issue. Gary Morris UUCP: ucbvax!ucsd!telesoft!garym TeleSoft, San Diego telesoft!garym@ucsd.edu (619) 457-2700 ARPA: telesoft!garym@ucsd.ARPA