Skip to content

gh-150534: Add C23 half-turn trigonometric *pi functions#150555

Open
jepler wants to merge 21 commits into
python:mainfrom
jepler:c23-math-pifuns
Open

gh-150534: Add C23 half-turn trigonometric *pi functions#150555
jepler wants to merge 21 commits into
python:mainfrom
jepler:c23-math-pifuns

Conversation

@jepler
Copy link
Copy Markdown
Contributor

@jepler jepler commented May 28, 2026

See #150534 and https://discuss.python.org/t/add-half-turns-functions-cospi-et-al-to-math-module-following-c23-ieee754-2019/107550/5 for discussion and context.

The following functions are added to the math module:

  • acospi
  • asinpi
  • atanpi
  • atan2pi
  • cospi
  • sinpi
  • tanpi

The following aspects of a new feature are covered in this pull request:

  • Add tests
  • Add documentation including NEWS.d & whatsnew
  • Add configure-time checks for function presence
  • Regenerate configure

The math_testcases.txt cases are based on glibc's test cases, and their input & output values have been used. I supplemented this with tests of inf/nan arguments.

I extended math_testcases.txt so that it can test n-arg functions, and used it to test atan2pi.

Closes: #150534

jepler added 4 commits May 27, 2026 12:41
 * Add tests
 * Add documentation
 * Add configure-time checks for function presence
 * Regenerate configure

No news item added, pending creation of a github issue.

As committed, the local implementation of the functions is always
used. For production, the #undefs should be removed so that the
presence of the functions is detected by configure and used by
mathmodule.
@read-the-docs-community
Copy link
Copy Markdown

read-the-docs-community Bot commented May 28, 2026


acospi10000 acospi 0.0 -> 0.5
acospi10001 acospi -0.0 -> 0.5
acospi10002 acospi 1.0 -> 0.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also test infinite/nan input and values with magnitude > 1. Include appropriate FPE flags, where it's required by the C23 Annex F.

With this, I think you can drop separate tests in the test_math.py for new functions.

Comment thread Doc/library/math.rst
Comment thread Doc/library/math.rst Outdated
Comment on lines +650 to +654
The vector in the plane from the origin to point ``(x, y)`` makes this angle
with the positive X axis. The point of :func:`atan2pi` is that the signs of both
inputs are known to it, so it can compute the correct quadrant for the angle.
For example, ``atanpi(1)`` and ``atanpi2(1, 1)`` are both ``1/4``, but
``atanpi2(-1, -1)`` is ``-3/4``.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The vector in the plane from the origin to point ``(x, y)`` makes this angle
with the positive X axis. The point of :func:`atan2pi` is that the signs of both
inputs are known to it, so it can compute the correct quadrant for the angle.
For example, ``atanpi(1)`` and ``atanpi2(1, 1)`` are both ``1/4``, but
``atanpi2(-1, -1)`` is ``-3/4``.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you, committed locally and will push shortly. (atanpi2 -> atan2pi)

Comment thread Modules/mathmodule.c Outdated
Comment on lines +76 to +82
#undef HAVE_ACOSPI
#undef HAVE_ASINPI
#undef HAVE_ATANPI
#undef HAVE_ATAN2PI
#undef HAVE_COSPI
#undef HAVE_SINPI
#undef HAVE_TANPI
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you did this? libm functions will be not used, isn't?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mistake, deleted. I add/remove this block for local testing to make sure that my implementations of the new functions are being tested.

Comment thread Modules/mathmodule.c Outdated
Comment on lines +226 to +227
integral or close to an integer). It conforms to IEEE 754-2008.
Special cases are handled as for glibc 2.41 __acospi.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? I don't see this function in the IEEE 754-2008. I think it come with the IEEE 754-2019 (Table 9.1).

I think it's better to reference the Annex F of C23 standard. Same below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I finally noticed that I copypasted "IEEE 754-2008" from an old internal comment on m_sinpi without checking. It'll be good to have this corrected.

Comment thread Modules/mathmodule.c Outdated
return cos(x);
}
x = fabs(x - 2.0 * round(0.5 * x));
if (islessequal(x, 0.25)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As argument is finite - it doesn't make sense to use "silent" comparison functions:

Suggested change
if (islessequal(x, 0.25)) {
if (x <= 0.25) {

Comment thread Modules/mathmodule.c Outdated
if (x == 0.5) {
return 0.0;
}
if (islessequal(x, 0.75)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (islessequal(x, 0.75)) {
if (x <= 0.75) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed.

Comment thread Modules/mathmodule.c
{"asinh", math_asinh, METH_O, math_asinh_doc},
{"asinpi", math_asinpi, METH_O, math_asinpi_doc},
{"atan", math_atan, METH_O, math_atan_doc},
{"atan2", _PyCFunction_CAST(math_atan2), METH_FASTCALL, math_atan2_doc},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated change.

Comment thread Modules/mathmodule.c Outdated
Comment on lines +225 to +226
acos(x)/pi, giving accurate results for all finite x (especially x
integral or close to an integer). It conforms to IEEE 754-2008.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is misleading. Apparently, it's copy-pasted stub from sinpi/cospi, etc. Please correct this. Same below for other arc-functions.

Comment thread Doc/library/math.rst
Copy link
Copy Markdown
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add also a What's New entry.

Comment thread Doc/library/math.rst
Comment thread Doc/library/math.rst Outdated

.. function:: atanpi(x)

Return the arc tangent of *x*, in half-turns. The result is between ``-1/2`` and
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the result is a float, should not we use 0.5 instead 0f 1/2? The same question for other documentation and examples.

Copy link
Copy Markdown
Contributor Author

@jepler jepler May 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great question. These doc blocks were made by copypaste of the existing block (e.g., atan) then removing pi.

It's clear why an expression using pi is used in the existing atan2 docs. However, it's possible to ask which would be clearer in the atan2 comment: -.75*pi or -3*pi/4. I feel like the answer to this might make it clear whether -.75 or -3/4 is clearer in the new function's documentation.

Thoughts?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-3*pi/4 is an expression. I think it is clearer in such way. But for atan2pi we can use exact number: -0.75.

I don't have a firm opinion, I'm just pointing out a possible option. I am fine with any option.

@jepler
Copy link
Copy Markdown
Contributor Author

jepler commented May 29, 2026

Branch updated based on review comments. Thank you for your reviews.

Copy link
Copy Markdown
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 👍

Comment thread Modules/mathmodule.c Outdated
Comment on lines +217 to +218
acos(x)/pi, giving accurate results for all finite x (especially x
integral or close to an integer). It conforms to C23 Annex 'F'.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still is misleading, just as for other arc-functions.

Comment thread Modules/mathmodule.c Outdated
/*
acos(x)/pi, giving accurate results for all finite x (especially x
integral or close to an integer). It conforms to C23 Annex 'F'.
Special cases are handled as for glibc 2.41 __acospi.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is redundant, special cases described by Annex:

Suggested change
Special cases are handled as for glibc 2.41 __acospi.

Same for all comments.

Comment thread Doc/library/math.rst
@jepler
Copy link
Copy Markdown
Contributor Author

jepler commented May 30, 2026

I've updated the PR with additional comment changes as requested.

@jepler jepler requested a review from skirpichev May 30, 2026 17:32
Comment thread Doc/library/math.rst
Comment on lines +659 to +660
For example, ``atanpi(1)`` and ``atan2pi(1, 1)`` are both ``.25``, but
``atan2pi(-1, -1)`` is ``-.75``.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For example, ``atanpi(1)`` and ``atan2pi(1, 1)`` are both ``.25``, but
``atan2pi(-1, -1)`` is ``-.75``.
For example, ``atanpi(1)`` and ``atan2pi(1, 1)`` are both ``0.25``, but
``atan2pi(-1, -1)`` is ``-0.75``.

Let's be consistent with fractional values.

Comment thread Modules/mathmodule.c
{"atan2", _PyCFunction_CAST(math_atan2), METH_FASTCALL, math_atan2_doc},
{"atanh", math_atanh, METH_O, math_atanh_doc},
{"atan2pi", _PyCFunction_CAST(math_atan2pi), METH_FASTCALL, math_atan2pi_doc},
{"atanpi", math_atanpi, METH_O, math_atanpi_doc},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    {"atanpi",          math_atanpi,    METH_O,       math_atanpi_doc},

make it aligned with METH_O of atanh

@picnixz picnixz changed the title gh-150534: Add C23 math "*pi" functions gh-150534: Add C23 half-turn trigonometric *pi functions May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add 'half turns' functions (cospi et al) to math module following C23 & IEEE754-2019

5 participants