https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93871

--- Comment #26 from Thomas Henlich <thenlich at gcc dot gnu.org> ---
Created attachment 47914
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47914&action=edit
Demonstration of range reduction

There is a danger of some inaccuracy in the degree trigonometric functions
(sind, cosd, tand, cotand) because a full period of 360 degrees can not be
expressed accurately in radians.

This can be circumvented by using some trigonometric identities to reduce the
range and also place the inaccurate x range to where |dy/dx|→min, and away from
y values near zero toward high y values so that the error is mostly cancelled.

This is a best effort to still be able to use the standard library functions
but also get an increased accuracy expected from the degree functions.

Thus:
1. Calculate cosd(x) = sind(90 - x)
2. Calculate cotand(x) = tand(90 - x)
3. Reduce range of sind() argument from (0...360) further to x-360 if it is
above 270, and to 180-x if it is above 90

Considering the demonstration program:

$ gf10 -fdec-math periods.f90 && ./a.exe
 cos(   90.0000000     )=  -4.37113883E-08   0.00000000
 sin(   180.000000     )=  -8.74227766E-08   0.00000000
 cos(   270.000000     )=   1.19248806E-08   0.00000000
 sin(  -360.000000     )=  -0.00000000       0.00000000
 sin(   36000000.0     )=   0.00000000       0.00000000
 sin(   36000180.0     )=  -8.74227766E-08   0.00000000
 cotan(   90.0000000     )=  -4.37113883E-08   0.00000000
$ gf10 -fdec-math -fdefault-real-8 periods.f90 && ./a.exe
 cos(   90.000000000000000 )=   6.1230317691118863E-017  0.0000000000000000
 sin(   180.00000000000000 )=   1.2246063538223773E-016   0.0000000000000000
 cos(   270.00000000000000 )=  -1.8369095307335659E-016   0.0000000000000000
 sin(  -360.00000000000000 )=  -0.0000000000000000        0.0000000000000000
 sin(   36000000.000000000 )=   0.0000000000000000        0.0000000000000000
 sin(   36000180.000000000 )=   1.2246063538223773E-016   0.0000000000000000
 cotan( 90.000000000000000 )=   6.1230317691118863E-017   0.0000000000000000

showing that values for all multiples of 90 degrees can be computed to be
exactly zero.

Reply via email to