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-Thread: 103376,acba876b1e3c9639 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news3.google.com!proxad.net!news.in2p3.fr!in2p3.fr!news.ecp.fr!news.jacob-sparre.dk!pnx.dk!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: GNAT Optimization of Constant Expressions Date: Fri, 18 May 2007 12:40:16 -0500 Organization: Jacob's private Usenet server Message-ID: References: <1179355028.624745.258370@q75g2000hsh.googlegroups.com> <464cb4cd$1_3@news.bluewin.ch> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: jacob-sparre.dk 1179509895 11729 69.95.181.76 (18 May 2007 17:38:15 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Fri, 18 May 2007 17:38:15 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1807 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1807 Xref: g2news1.google.com comp.lang.ada:15839 Date: 2007-05-18T12:40:16-05:00 List-Id: "Ray Blaak" wrote in message news:u1whep09x.fsf@STRIPCAPStelus.net... > "Randy Brukardt" writes: > > One example is: > > Y := (X - 0.5) - 0.5; > > > > You might think that replacing this with > > Y := X - 1.0; > > would be a good idea, but actually it reduces the accuracy of the result > > I don't understand this. Both 0.5 and 1.0 have "exact" binary representations > right? > > Can you give a value of X where this would hold? I'm not a numerical analysist, I only play at one when implementing compilers... ;-) but let me give my understanding. If the machine does not keep extra precision between operations (that is, the floating point registers are the same size as the in-memory representation), and abs X is < 1.0, then (X - 0.5) - 0.5 will have one more bit of precision than X - 1.0 will. That occurs because in order to add or subtract, the smaller value has to be shifted to match the larger value, which will cause bits to fall off the end of the smaller value. 1.0 requires more shifting than 0.5 does. This sort of expression is common in trig. libraries (for instance, in a software implementation of Sin). And a trig. library is the last place that you would want a hair-brained optimizer losing accuracy! It should be pointed out that on Intel hardware, the original condition does not hold (extra precision *may* be kept between operations). However, it still might hold if common subexpressions are preevaluated into memory (as in the OP's program with the unused constants). Thus, the optimizer still has to be wary of reordering (and most optimizers are designed to work on a variety of hardware, not just Intel chips.). Randy.