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=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.13.206.193 with SMTP id q184mr7954322ywd.151.1477175939331; Sat, 22 Oct 2016 15:38:59 -0700 (PDT) X-Received: by 10.157.0.40 with SMTP id 37mr962342ota.16.1477175939274; Sat, 22 Oct 2016 15:38:59 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.glorb.com!f6no1548898qtd.0!news-out.google.com!w143ni1894itb.0!nntp.google.com!66no1899602itl.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sat, 22 Oct 2016 15:38:58 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=2601:191:8380:3b80:5985:2c17:9409:aa9c; posting-account=fdRd8woAAADTIlxCu9FgvDrUK4wPzvy3 NNTP-Posting-Host: 2601:191:8380:3b80:5985:2c17:9409:aa9c References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <92d24324-3faa-4960-b138-1dd981fb9c0b@googlegroups.com> Subject: Re: Ada.Numerics, Accuracy of trigonometric functions From: Robert Eachus Injection-Date: Sat, 22 Oct 2016 22:38:59 +0000 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:32163 Date: 2016-10-22T15:38:58-07:00 List-Id: On Friday, October 7, 2016 at 6:13:50 AM UTC-4, Markus Sch=C3=B6pflin wrote= : > I'm puzzled by the seemingly bad accuracy of calling COS on a large value= of type Short_Float. >=20 > Given the following procedure which calculates y1 =3D cos(2**32) and y2 = =3D=20 > cos(2**32 mod 2*PI): =20 > Now for the questions: Is my reasoning above correct? Why does using the = cycle=20 > parameter not help? Do other Ada compilers give the same bad result in th= is=20 > case? Should I report this as an error to AdaCore? Yes, you should report this as an error to AdaCore. The correct fix is to = raise Constraint_Error, and mention why in the documentation. I'd like to= raise Argument_Error, but even mentioning that possibility may result in l= ots more posts than the issue is worth. I tried your program both with Short and Long_Float, and values of X up to = 2**32 with and without scaling. The unscaled numbers worked up perfectly u= ntil 2**32 (see below). There seems to be some rounding somewhere in the s= caled version. It's fine up to about 2**20. The unscaled numbers are accu= rate to 14 digits up until 2**32: Size of Long_FLOAT =3D 64 Maximum relative error of COS =3D 4.44089209850063E-16 Angle threshold =3D 26 X**I =3D 1.00; COS(X**I) =3D 0.54030230586814; Scaled Cos =3D 0.5= 4030230586814 X**I =3D 2.00; COS(X**I) =3D -0.41614683654714; Scaled Cos =3D-0.4= 1614683654714 X**I =3D 4.00; COS(X**I) =3D -0.65364362086361; Scaled Cos =3D-0.6= 5364362086361 X**I =3D 8.00; COS(X**I) =3D -0.14550003380861; Scaled Cos =3D-0.1= 4550003380861 X**I =3D 16.00; COS(X**I) =3D -0.95765948032338; Scaled Cos =3D-0.9= 5765948032338 X**I =3D 32.00; COS(X**I) =3D 0.83422336050651; Scaled Cos =3D 0.8= 3422336050651 X**I =3D 64.00; COS(X**I) =3D 0.39185723042955; Scaled Cos =3D 0.3= 9185723042955 X**I =3D 128.00; COS(X**I) =3D -0.69289582192017; Scaled Cos =3D-0.6= 9289582192017 X**I =3D 256.00; COS(X**I) =3D -0.03979075993116; Scaled Cos =3D-0.0= 3979075993116 X**I =3D 512.00; COS(X**I) =3D -0.99683339084820; Scaled Cos =3D-0.9= 9683339084820 X**I =3D 1024.00; COS(X**I) =3D 0.98735361821985; Scaled Cos =3D 0.9= 8735361821985 X**I =3D 2048.00; COS(X**I) =3D 0.94973433482365; Scaled Cos =3D 0.9= 4973433482365 X**I =3D 4096.00; COS(X**I) =3D 0.80399061348585; Scaled Cos =3D 0.8= 0399061348585 X**I =3D 8192.00; COS(X**I) =3D 0.29280181314670; Scaled Cos =3D 0.2= 9280181314670 X**I =3D 16384.00; COS(X**I) =3D -0.82853419643601; Scaled Cos =3D-0.8= 2853419643601 X**I =3D 32768.00; COS(X**I) =3D 0.37293782932771; Scaled Cos =3D 0.3= 7293782932771 X**I =3D 65536.00; COS(X**I) =3D -0.72183475091266; Scaled Cos =3D-0.7= 2183475091266 X**I =3D 131072.00; COS(X**I) =3D 0.04209081525030; Scaled Cos =3D 0.0= 4209081525030 X**I =3D 262144.00; COS(X**I) =3D -0.99645672654313; Scaled Cos =3D-0.9= 9645672654313 X**I =3D 524288.00; COS(X**I) =3D 0.98585201574610; Scaled Cos =3D 0.9= 8585201574611 X**I =3D 1048576.00; COS(X**I) =3D 0.94380839390131; Scaled Cos =3D 0.9= 4380839390132 X**I =3D 2097152.00; COS(X**I) =3D 0.78154856879715; Scaled Cos =3D 0.7= 8154856879720 X**I =3D 4194304.00; COS(X**I) =3D 0.22163633077774; Scaled Cos =3D 0.2= 2163633077789 X**I =3D 8388608.00; COS(X**I) =3D -0.90175467375876; Scaled Cos =3D-0.9= 0175467375863 X**I =3D 16777216.00; COS(X**I) =3D 0.62632298329153; Scaled Cos =3D 0.6= 2632298329196 X**I =3D 33554432.00; COS(X**I) =3D -0.21543904120159; Scaled Cos =3D-0.2= 1543904120051 X**I =3D 67108864.00; COS(X**I) =3D -0.90717203905228; Scaled Cos =3D-0.9= 0717203905196 X**I =3D 134217728.00; COS(X**I) =3D 0.64592221687655; Scaled Cos =3D 0.6= 4592221687210 X**I =3D 268435456.00; COS(X**I) =3D -0.16556897949058; Scaled Cos =3D-0.1= 6556897950206 X**I =3D 536870912.00; COS(X**I) =3D -0.94517382606090; Scaled Cos =3D-0.9= 4517382605945 X**I =3D 1073741824.00; COS(X**I) =3D 0.78670712294119; Scaled Cos =3D 0.7= 8670712290611 X**I =3D 2147483648.00; COS(X**I) =3D 0.23781619457280; Scaled Cos =3D 0.2= 3781619446243 X**I =3D 4294967296.00; COS(X**I) =3D 1.00000000000000; Scaled Cos =3D-0.8= 8688691530282 [2016-10-22 18:28:01] process terminated successfully, elapsed time: 00.34s with ADA.NUMERICS.GENERIC_ELEMENTARY_FUNCTIONS;=20 with ADA.TEXT_IO; use ADA.TEXT_IO;=20 with ADA.Long_FLOAT_TEXT_IO; use ADA.Long_FLOAT_TEXT_IO;=20 procedure TEST_TRIG is=20 MRE_COS : constant :=3D 2.0 * Long_FLOAT'MODEL_EPSILON;=20 THRESHOLD : constant :=3D Long_FLOAT'MACHINE_MANTISSA / 2;=20 Pi : constant :=3D Ada.Numerics.Pi; Two_Pi : constant :=3D Pi + Pi; package EF is new ADA.NUMERICS.GENERIC_ELEMENTARY_FUNCTIONS (Long_FLOAT= );=20 X : constant Long_FLOAT :=3D 2.0; Temp: Integer; Y : constant Long_FLOAT :=3D EF.COS (X);=20 begin=20 PUT_LINE ("Size of Long_FLOAT =3D " & POSITIVE'IMAGE (Long_FLOAT'SIZE))= ;=20 PUT_LINE ("Maximum relative error of COS =3D " & Long_FLOAT'IMAGE (MRE_= COS));=20 PUT_LINE ("Angle threshold =3D " & POSITIVE'IMAGE (THRESHOLD));=20 for I in 0..32 loop PUT ("X**I =3D "); PUT (X**I, Fore =3D> 10, Aft =3D> 2, EXP = =3D> 0);=20 PUT ("; COS(X**I) =3D "); PUT (EF.Cos(X**I), EXP =3D> 0); Temp :=3D Integer(X**I/(2.0*Pi)); Put ("; Scaled Cos =3D"); PUT (EF.Cos(Long_Float(Long_Long_Float(X**I) - Long_Long_Float'(Long_Long_Float(Temp)*Two_Pi))), EXP =3D> 0)= ; NEW_LINE; =20 end loop; end TEST_TRIG;