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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,c7d533acec91ae16 X-Google-Attributes: gid103376,public From: Samuel Mize Subject: Re: Question for the folks who designed Ada95 Date: 1999/04/27 Message-ID: <7g4jqm$1rkg@news1.newsguy.com>#1/1 X-Deja-AN: 471505401 References: <7g2qu4$ca4$1@usenet.rational.com> Organization: ImagiNet Communications, Ltd. User-Agent: tin/pre-1.4-981002 ("Phobia") (UNIX) (AIX/3-2) Newsgroups: comp.lang.ada Date: 1999-04-27T00:00:00+00:00 List-Id: Corey Ashford wrote: > > About modular types. ... > Why didn't Ada95 make a shift operator a first-class > operator on modular types. ... > The problem with the interfaces package shift > operators is that they have fixed types. So it's > difficult to write code for types whose size can vary. ... > Any thoughts as to why the shift operator wasn't given > a better treatment? I'm not one of "the folks who designed Ada95" but I have a guess. I expect it was because shifting is usually a low-level thing to do, which comes up in interfaces to the machine. So, the concern was to make it available for the types that have direct machine support on a given architecture. Nobody cared about other moduluses (modulii?). Also, bear in mind that modular types don't have to have a power-of-2 modulus. Consider a mod 5 type. If its value before shifting is three, its lowest four bits are: 0011 Shift left 1, and its bits are: 0110 which is 6, which is out of range for the type. Should we get a constraint error, or should it saturate to 5, or should it wrap to 6 mod 5 (0001)? The last makes the most sense, in terms of modular numbers, and would do what you want for a power-of-two modulus. But it destroys the meaning of shifting. Any of the above adds complexity -- you're no longer doing an efficient shift operation, but shifting and checking constraints. Of course, you could expect a compiler to elide all this in the case of a power-of-two modulus. But you can't test for that, so you can't make it a requirement. It's reasonable behavior to expect, but so is implementing division by a constant power of two as a simple shift. > Or am I all wet, and there's really a good way to do shifts? For a non-hardware-supported power-of-two-modulus unsigned type, you will need to do a shift, then mask the result down under your modulus. You can do this with a type from Interfaces that has more bits than your type. For instance: with Interfaces; use Interfaces; ... type My_Type is mod 2 ** 30; My_Var: My_Type; ... My_Var := My_Type (Shift_Left (Unsigned_32 (My_Var), 3) mod 2 ** 30); The conversion to Unsigned_32 should take no cycles, it's implicit in reading the value into a register to work on it. The mod 2**30 has to be done anyway, as I described above, since the machine doesn't directly support a mod 2**30 type (or it would be in Interfaces). I'd expect a mod operation using a static power of two to be implemented as a simple bit-mask operation. I wouldn't expect the conversion to My_Type to do a range check, since the compiler can tell statically that the value can't be out of range. If you're extremely exercised about CPU time you'll be compiling with range-checks off anyway. So this should be as efficient as possible. Best, Sam Mize -- Samuel Mize -- smize@imagin.net (home email) -- Team Ada Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam