]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-154146: Fix accuracy of the math.acospi() fallback near 1 (GH-154148)
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 20 Jul 2026 05:56:50 +0000 (08:56 +0300)
committerGitHub <noreply@github.com>
Mon, 20 Jul 2026 05:56:50 +0000 (08:56 +0300)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Misc/NEWS.d/next/Library/2026-07-19-19-05-00.gh-issue-154146.acospi.rst [new file with mode: 0644]
Modules/mathmodule.c

diff --git a/Misc/NEWS.d/next/Library/2026-07-19-19-05-00.gh-issue-154146.acospi.rst b/Misc/NEWS.d/next/Library/2026-07-19-19-05-00.gh-issue-154146.acospi.rst
new file mode 100644 (file)
index 0000000..5dbddba
--- /dev/null
@@ -0,0 +1,2 @@
+Fix accuracy of :func:`math.acospi` for arguments close to 1
+on platforms that do not provide ``acospi()`` in libm.
index 64e5372d73d2f29b5644c024ddac35c779de2812..eaa1850b8aee1acd94cdb6fac4f2497f410356fd 100644 (file)
@@ -220,6 +220,12 @@ static const double logpi = 1.144729885849400174143427351353058711647;
 static double
 m_acospi(double x)
 {
+    if (x >= 0.5) {
+        /* acos(x) = 2*asin(sqrt((1 - x)/2)).  1 - x is exact here.
+           Some libms (old fdlibm derivatives) lose precision in acos(x)
+           near x = 1, while asin() is accurate for small arguments. */
+        return 2.0*asin(sqrt((1.0 - x)/2.0))/pi;
+    }
     double r = acos(x)/pi;
     if (isgreater(r, 1.0)) {
         return 1.0;