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,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,4ac8a7e7d3e637dc X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-23 14:42:35 PST Path: archiver1.google.com!news2.google.com!news.maxwell.syr.edu!wn14feed!worldnet.att.net!204.127.198.203!attbi_feed3!attbi.com!attbi_s51.POSTED!not-for-mail Message-ID: <3F984AF5.6030703@comcast.net> From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20021120 Netscape/7.01 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Is there a better (Ada) way? References: <20619edc.0310221056.4c92d10c@posting.google.com> <3F96ED50.2040009@comcast.net> <20619edc.0310230857.5da5446f@posting.google.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit NNTP-Posting-Host: 24.34.139.183 X-Complaints-To: abuse@comcast.net X-Trace: attbi_s51 1066945354 24.34.139.183 (Thu, 23 Oct 2003 21:42:34 GMT) NNTP-Posting-Date: Thu, 23 Oct 2003 21:42:34 GMT Organization: Comcast Online Date: Thu, 23 Oct 2003 21:42:34 GMT Xref: archiver1.google.com comp.lang.ada:1550 Date: 2003-10-23T21:42:34+00:00 List-Id: Mike Silva wrote: > "Robert I. Eachus" wrote in message news:<3F96ED50.2040009@comcast.net>... > >>> R16 := R16 + Reg16_t( Integer( PB.offset5 ) mod Reg16_t'Modulus ); >>>-- the above line works, but is it good Ada, or C-in-Ada? >> >> R16 := R16 + Reg16_t(PB.offset5); >> >>Should do exactly the same thing--but it doesn't. > > > Do you mean that the language should have been defined so that the > conversion in the 2nd line acts like the 1st, with negative numbers? > Or ??? > > Mike Yes. I believe that this will be "fixed" in the next version of the standard, but for now you will find compilers that raise Constraint_Error when converting a negative value to a modular type. Suppressing Constraint_Error for this one line makes it all come out right, if there is nothing that should be a Constraint_Error. It is one of those nasty complex glitches that make language definition so hard. There may not be a valid representation for a negative value of an unsigned type, so it looks like the "right" rule. But in reality, there must be a valid representation of the current value--the current one--and arithmetic works correctly after a possible sign extension for modular types with binary modulii. Incidently I thought of what may be a better way to do it, but to do it efficiently is tricky. Define a sign extention intrinsic operation, then do a normal addition. This works great on most hardware. Do a left shift that puts the bits in the high order position, then a sign extending right shift. Not great on a Pentium 4, but most other processors have a barrel-shifter that can do the two instructions quickly. And you can always write: if PB.offset5 >= 0 then R16 := R16 + Reg16_t(PB.offset5); else R16 := R16 - Reg16_t(-PB.offset5); end if; On some compilers you will get better performance than the version with the explicit mod operation, since even 16-bit division tends to be slow. But as I said the best code is probably to use pragma Suppress(Range_Check, Reg16_t); I can't imagine any case other than this where you might want the check to be made for a binary modular type like Reg16_t, so you can probably put the pragma with the type declaration. Hmmm, thinking more about it, the compiler is not required to do the sign extension in that case, but the following should always work right: function To_Reg16(Value: in Offset5_t) return Reg16_t is type Integer16 is range -2**15..2**15-1; for Integer16'Size use 16; function UC is new Ada.Unchecked_Conversion(Integer16, Reg16_t); begin return UC(Integer16(Value)); end To_Reg16; pragma Inline(To_Reg16); A lot of work to eliminate one mod operation, but now you can write: R16 := To_Reg16(PB.offset5); And be sure it is portable. If you have a lot of these operations, it may be worth it. Of course, it will take an awful lot of instances to justify all this analysis, but I think this is all covered under the learning experience heading. The lesson that should be coming through is that Ada programmers care a lot about making the code look pretty and easy to read and understand. That doesn't mean that we don't care about efficiency. We just go out of our way to hide the messy parts of the code in some function hidden in some package body. Oh, and that Ada programmers tend to have trouble sleeping if they write code that is compiler dependent when it doesn't have to be. ;-) -- Robert I. Eachus "Quality is the Buddha. Quality is scientific reality. Quality is the goal of Art. It remains to work these concepts into a practical, down-to-earth context, and for this there is nothing more practical or down-to-earth than what I have been talking about all along...the repair of an old motorcycle." -- from Zen and the Art of Motorcycle Maintenance by Robert Pirsig