Re: Fw: Error in documentation for tan(), and poor implementation of sin() and cos()

Paul Zimmermann <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <p9u0tsqa3rbv.fsf@thym>
       Dear Stefan,

I confirm your values, that we missed in our comparison [1], with maximal error of 268 ulps
for sin, 179 ulps for cos, and 268 ulps for tan:

zimmerma@thym:~/svn/tbd/20/src/binary64$ ./doit.glibc sin 1000
Checking sin with glibc-2.43/build and rndn
NEW sin 0 -1 0x1.2419db13f80ap+50 [268] [2.68e+02] 267.972 267.9719864551183
zimmerma@thym:~/svn/tbd/20/src/binary64$ ./doit.glibc cos 1000
Checking cos with glibc-2.43/build and rndn
NEW cos 0 -1 0x1.8577cec54ab8p+47 [179] [1.79e+02] 178.982 178.9813243034122
zimmerma@thym:~/svn/tbd/20/src/binary64$ ./doit.glibc tan 1000
Checking tan with glibc-2.43/build and rndn
NEW tan 0 -1 0x1.2419db13f80ap+50 [268] [2.68e+02] 267.972 267.9719864551183

Paul Zimmermann

[1] https://members.loria.fr/PZimmermann/papers/accuracy.pdf

> From: "Stefan Kanthak" <[email protected]>
> Cc: <[email protected]>
> Date: Tue, 7 Jul 2026 22:57:30 +0200
> Organization: Me, myself & IT
> 
> "Carlos O'Donell" <[email protected]> wrote:
> 
> > On 7/7/26 10:15 AM, Stefan Kanthak wrote:
> >> Hi maintainers,
> >>
> >> <https://sourceware.org/glibc/manual/latest/html_node/Trig-Functions.html>
> >> states:
> >
> > Stefan,
> >
> > Thank you for raising this issue.
> >
> > May you please report this to [email protected] or report a bug
> > in bugzilla with component glibc?
> >
> > Please see:
> > https://sourceware.org/glibc/wiki/FilingBug
> 
> This page only shows "Dein Browser wird geprüft!" and stalls.
> So my two part bug report goes here, per mail.
> 
> PART 1
> ~~~~~~
> 
> <https://sourceware.org/glibc/manual/latest/html_node/Trig-Functions.html>
> states:
> 
> | Mathematically, the tangent function has singularities at odd multiples
> | of pi/2. If the argument x is too close to one of these singularities,
> | tan will signal overflow.
> 
> There exists but no (double-precision) floating-point number for which tan()
> overflows or cos() yields 0, so signalling overflow respectively underflow
> is (or would be) wrong!
> 
> Shown by William Kahan MANY years ago, 6381956970095103 * 2**797 is THE
> double-precision floating-point number closest to a multiple of pi/2 -- it
> is about 4.687165924254627611e-19 or 0x1.14AE72E6BA22Fp-61 smaller than pi/2.
> 
> >From the identities
>     tan(x) = sin(x) / cos(x),
>     sin(x + pi) = cos(x + pi/2),
>     cos(x + pi) = -sin(x + pi/2)
> and the expansion of the Madhava-Newton series for sin(x) and cos(x),
>     cos(x) = x**0 / 0! - x**2 / 2! + ...
>            = 1 - x**2 / 2 + ...
>     sin(x) = x**1 / 1! - x**3 / 3! + ...
>            = x - x**3 / 6 + ...
> follows for double-precision floating-point numbers r,
> r**2 / 2 + 1 = 1 or |r| < 2**-25.5 ~ 2.107342425544701589e-8e-8,
>     cos(r) = -1
>     sin(r) = r
>     tan(r) = -r
> as well as
>     cos(pi/2 ± r) = -sin ±r
>     sin(pi/2 ± r) = 1
>     tan(pi/2 ± r) = -1 / ±r
> 
> The maximum absolute value for the double-precision tan() is therefore about
> 2.133485385753703844e+18, i.e. 290 orders of magnitude beyond overflow!
> 
> Evaluation of the maximum/minimum values for long double is left as an
> exercise.
> 
> 
> PART 2
> ~~~~~~
> 
> >> <https://sourceware.org/glibc/manual/latest/html_node/Errors-in-Math-Functions.html>
> >> states:
> >>
> >> | . Each function with a floating-point result behaves as if it computes an
> >> |   infinite-precision result that is within a few ulp of the mathematically
> >> |   correct value of the function [...]
> >>
> >> How much are "a few ulp"? Does 179 count as "few"?
> >
> > Generally <10 ULP. No, 179 does not count as a few. Though there are known outliers
> > that are more than 10 ULP.
> >
> > Please report them as bugs.
> 
> <https://godbolt.org/noscript/z/M9Ks87Wx9> is a slightly bigger demonstration -- it
> feeds integers which are near integral multiples of pi, pi/2 or pi/4 and exactly
> representable as double-precision floating-point numbers to cos(), sin() and tan()
> and prints a line if the value computed during runtime, i.e. by GLIBC, differs by
> more than 2 ULP from the value computed during compile time, i.e. by GCC.
> 
> It shows errors of 269 ULP for 72 sin/tan, 262 ULP for 66 tan, and 179 ULP for 66 cos!
> 
>   61 tan
>       65398140378926      -68524021915772.6328  -0x1.f293efe103e51p+45  -0x1.f293efe103e4fp+45      -68524021915772.6172
>   62 cos
>           74357078147863  -7.42638965257211217e-15  -0x1.0b905acac1b53p-47  -0x1.0b905acac1b51p-47  -7.42638965257210901e-15
>   62 tan            74357078147863       134654932852015.438   0x1.e9df2dc274bdcp+46    0x1.e9df2dc274bep+46
> 134654932852015.5
>   63 sin
>          139755218526789  -7.16703280049355271e-15  -0x1.023835bd45532p-47  -0x1.023835bd45536p-47  -7.16703280049355902e-15
>   63 tan           139755218526789   7.16703280049355271e-15   0x1.023835bd45532p-47   0x1.023835bd45536p-47
> 7.16703280049355902e-15
>   65 sin           148714156295726   1.48527793051442243e-14   0x1.0b905acac1b53p-46   0x1.0b905acac1b51p-46
> 1.4852779305144218e-14
>   65 tan
>         148714156295726  -1.48527793051442243e-14  -0x1.0b905acac1b53p-46  -0x1.0b905acac1b51p-46   -1.4852779305144218e-14
>   66 cos           214112296674652   2.59356852078558913e-16   0x1.2b04a1af8c415p-52   0x1.2b04a1af8c362p-52
> 2.59356852078550088e-16
>   66 tan           214112296674652          3855691461342618   0x1.b65763fd56b34p+51   0x1.b65763fd56c3ap+51
> 3855691461342749
>   67 sin           279510437053578   1.43340656009871054e-14   0x1.023835bd45532p-46   0x1.023835bd45536p-46
> 1.4334065600987118e-14
>   67 tan           279510437053578   1.43340656009871054e-14   0x1.023835bd45532p-46   0x1.023835bd45536p-46
> 1.4334065600987118e-14
>   68 sin
>        288469374822515  -7.68574650465067005e-15  -0x1.14e87fd83e173p-47  -0x1.14e87fd83e16cp-47    -7.685746504650659e-15
>   68 tan
>        288469374822515  -7.68574650465067005e-15  -0x1.14e87fd83e173p-47  -0x1.14e87fd83e16cp-47    -7.685746504650659e-15
>   69 sin           428224593349304   5.18713704157117826e-16   0x1.2b04a1af8c415p-51   0x1.2b04a1af8c362p-51
> 5.18713704157100176e-16
>   69 tan
>          428224593349304  -5.18713704157117826e-16  -0x1.2b04a1af8c415p-51  -0x1.2b04a1af8c362p-51  -5.18713704157100176e-16
>   70 sin           567979811876093   6.64831909633643459e-15   0x1.df0fd744991e1p-48   0x1.df0fd744991ffp-48
> 6.64831909633645826e-15
>   70 tan           567979811876093   6.64831909633643459e-15   0x1.df0fd744991e1p-48   0x1.df0fd744991ffp-48
> 6.64831909633645826e-15
>   71 sin
>          856449186698608  -1.03742740831423565e-15  -0x1.2b04a1af8c415p-50  -0x1.2b04a1af8c362p-50  -1.03742740831420035e-15
>   71 tan
>          856449186698608  -1.03742740831423565e-15  -0x1.2b04a1af8c415p-50  -0x1.2b04a1af8c362p-50  -1.03742740831420035e-15
>   72 sin          1284673780047912   1.55614111247135338e-15   0x1.c086f2875261fp-50   0x1.c086f28752513p-50
> 1.55614111247130053e-15
>   72 tan
>         1284673780047912  -1.55614111247135338e-15  -0x1.c086f2875261fp-50  -0x1.c086f28752513p-50  -1.55614111247130053e-15
> 
> >> With -DLIBM, i.e. sin() and cos() evaluated during runtime,
> >> <https://godbolt.org/noscript/z/x33TPr6vE> yields the following results:
> >>
> >>   5.31937264832654142e+255  -4.68716592425461995e-19  -0x1.14ae72e6ba227p-61
> >>            214112296674652   2.59356852078558913e-16   0x1.2b04a1af8c415p-52
> >>                                                                      ~~~
> >>             74357078147863  -7.42638965257211217e-15  -0x1.0b905acac1b53p-47
> >>             65398140378926   1.45934224530656633e-14   0x1.06e4484403842p-46
> >>
> >>            139755218526789  -7.16703280049355271e-15  -0x1.023835bd45532p-47
> >>            428224593349304   5.18713704157117826e-16   0x1.2b04a1af8c415p-51
> >>                                                                      ~~~
> >>            856449186698608  -1.03742740831423565e-15  -0x1.2b04a1af8c415p-50
> >>                                                                      ~~~
> >>
> >> Without -DLIBM, i.e. when GCC evaluates the functions at compile time, the
> >> results are:
> >>
> >>   5.31937264832654142e+255  -4.68716592425462765e-19  -0x1.14ae72e6ba22fp-61
> >>            214112296674652   2.59356852078550088e-16   0x1.2b04a1af8c362p-52
> >>                                                                      ~~~
> >>             74357078147863  -7.42638965257210901e-15  -0x1.0b905acac1b51p-47
> >>             65398140378926   1.45934224530656665e-14   0x1.06e4484403843p-46
> >>
> >>            139755218526789  -7.16703280049355902e-15  -0x1.023835bd45536p-47
> >>            428224593349304   5.18713704157100176e-16   0x1.2b04a1af8c362p-51
> >>                                                                      ~~~
> >>            856449186698608  -1.03742740831420035e-15  -0x1.2b04a1af8c362p-50
> >>                                                                      ~~~
> >>
> >> The values computed by GCC are correct, the underlined values computed by
> >> GLIBC are 179 ULP off!
> >
> > Thank you.
> >
> > -- 
> > Cheers,
> > Carlos.
> 
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.