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,65b3f028266fd999 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!postnews.google.com!y11g2000yqm.googlegroups.com!not-for-mail From: Ludovic Brenta Newsgroups: comp.lang.ada Subject: Re: Question about ordinary fixed point types. Date: Mon, 16 Aug 2010 03:03:59 -0700 (PDT) Organization: http://groups.google.com Message-ID: <2981f976-6252-4d4f-9e6e-b121622cd92f@y11g2000yqm.googlegroups.com> References: <4c685fac$0$2373$4d3efbfe@news.sover.net> <4c688e67$0$2389$4d3efbfe@news.sover.net> NNTP-Posting-Host: 153.98.68.197 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1281953039 17370 127.0.0.1 (16 Aug 2010 10:03:59 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Mon, 16 Aug 2010 10:03:59 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: y11g2000yqm.googlegroups.com; posting-host=153.98.68.197; posting-account=pcLQNgkAAAD9TrXkhkIgiY6-MDtJjIlC User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6,gzip(gfe) Xref: g2news1.google.com comp.lang.ada:13395 Date: 2010-08-16T03:03:59-07:00 List-Id: Jeffrey Carter wrote on comp.lang.ada: > Consider this example, which I 1st encountered in 1984: > > with Ada.Text_IO; > > procedure Fixed_Test is > =A0 =A0 type Money is delta 0.01 range -100.0 .. 100.0; > > =A0 =A0 Cent : constant Money :=3D Money'Delta; > > =A0 =A0 Change : Money :=3D 0.0; > begin -- Fixed_Test > =A0 =A0 Sum : for I in 1 .. 5 loop > =A0 =A0 =A0 =A0Change :=3D Change + Cent; > =A0 =A0 end loop Sum; > > =A0 =A0 Ada.Text_IO.Put_Line (Item =3D> Money'Image (Change) ); > end Fixed_Test; > > Typically, the 'Small will be 2#0.000_000_1#, and the program will output= 0.04. > The program adds the machine number closest to 'Delta (which is 'Small) e= ach > time, not 'Delta, so there's no "snapping" taking place, except in the > conversion of 0.01 to a machine number of type Money. Money is quite special; this is an area where approximation of a one cent to a power of two is not acceptable. Ada has decimal fixed-point types for this purpose. More generally, Ada allows the programmer to specify the 'Small with an attribute definition clause, so theoretically the exact solution to Peter's problem would be: Epsilon : constant :=3D Ada.Numerics.Pi / 2 ** 15; type Angle is delta Epsilon range -Ada.Numerics.Pi .. Ada.Numerics.Pi; for Angle'Small use Epsilon; This would, in theory, create the desired mapping from the integer range [-2**15 .. 2**15] to the real range [-Pi .. Pi] without wasting any machine numbers. However and unfortunately, ARM 3.5.9(21) allows an implementation to reject any 'Small that is not a power of two (and, in particular, decimal fixed-point types). I'm not sure whether GNAT supports arbitrary Smalls; from the doc, it seems that it actually rounds them down to a power of two no smaller than 2**(-63). -- Ludovic Brenta.