I will first post here because I don't want to flood DPO with a controversial thread. I didn't dig much in the issues so it might have already been discussed a bit more in detail elsewhere.
There are some functions in math.h that we don't export in math as some are useless for Python or just forgotten. We recently added isnormal and issubnormal but the following are missing:
It's only useful if FLT_RADIX != 2. Python only supports FLT_RADIX = 2 or 16 but I don't know how many systems have FLT_RADIX = 16. So I don't think we need it for now. logb also depends on FLT_RADIX but I think we can ignore it if we don't add scalbn.
DECISION: let's not add it as numpy doesn't have it and it has a confusing name (at least to me).
This one could be useful to handle possible signed zeros when doing fp artihmetic. Similarly, math currently lacks fmax and fmin which could useful if we support IEC 60559 because max(nan, inf) == nan and max(inf, nan) == inf which is incorrect (in both cases fmax would have returned inf on such systems).
DECISION: numpy has fmax and fmin and treat the NaNs correctly, but not fdim. For now, let's not add it.
This one is useful for implementing $t$-periodic functions for $t$ exactly representable as an fp-value. I don't know if users are expected to actually work in Python for such functions, but I think we can expose it.
DECISION: numpy doesn't have it and while it could be fine, it's actually really niche.
Now that we have normal and subnormal detection, I suggest we also add this function. This would however require new constants which may or may not be adequate as this would make the module a bit heavier. It was asked in #132908 (comment) but we didn't follow up with that later.
DECISION: I would personally like it but it would more for completeness rather than usefulness, and numpy doesn't have it so I won't push for it.
Useful for getting the sign of signed zeroes, infinities and NaN.
DECISION: I was wrong in my original statement as Mark pointed out but this one seems the most useful. So I'll work on it tomorrow.
I omitted some functions such as isless as they are directly implemented in Python and I don't think we should do something here. I also omitted rounding functions that depend on the rounding mode as those should be handled by Decimal instead.
Finally, it's unfortunate that we named math.gamma instead of math.tgamma as math.gamma could have been confused with Euler-Mascheroni's constant.
as well as signbit as it can be implemented as x <= 0
It can't, since signbit should distinguish signs of zeros: signbit(0.0) should return False or 0, while signbit(-0.0) should return True or 1. (There's a separate bikeshedding discussion to be had about whether signbit should return a bool or an int; both choices seem defensible.) It's a useful function (well, actually a macro in C world rather than a function). I've often wanted signbit in Python-land, usually in circumstances where I do care about the sign of zero, but it's at least easily (albeit not very efficiently) spelled as math.copysign(1.0, x) < 0.0.
it's unfortunate that we named math.gamma instead of math.lgamma
Guessing that you meant math.tgamma here? Python's math.lgamma exactly matches C99's math.lgamma.
C has its own history that led to the C99 function for 𝛤 being called tgamma rather than gamma: once upon a time, gamma computed the log of the absolute value of the mathematical Gamma function. The t in tgamma is there for disambiguation (meaning "true gamma"). Outside of the context of C, tgamma is a non-obvious name for something that computes the Gamma function. Since Python doesn't have the same historical baggage as C here, I think gamma was the right name to use for the Python function.
signbit seems to have good support. I also quickly checked with numpy, and there is numpy.signbit however numpy.fpclassify or np.fdim do not exist. np.fmax and np.fmin do exist though but let's decide it later.
I think remquo and isunordered are really too obscure for the Python user. First, isunordered may be safe a few lines but a helper function that is better named would be better. As for remquo, it doesn't exist in numpy and neither do scalbn nor logb (and they can really be confused with log in base b...).
I assume we don't consider anything outside of the C11? If not - e.g. rootn() (coming with C23) is good candidate.
I was thinking about exposing fenv.h, at least partially. Maybe to do this properly we should introduce context notion for floating-point math, just like the decimal module does: rounding modes, raise exceptions or not (see #133895), etc.
For this issue, no. It was mainly about those defined in C99 (and likely the same as in C11, I don't remember if there are differences). For other functions, I think we should have a separate issue.
We now have all needed C99/C11 functions. Others are really too niche to be added and even numpy doesn't have them, meaning that they are likely not useful even for them.
Activity
mdickinson commented on Jun 23, 2025
It can't, since signbit should distinguish signs of zeros: signbit(0.0) should return False or 0, while signbit(-0.0) should return True or 1. (There's a separate bikeshedding discussion to be had about whether signbit should return a bool or an int; both choices seem defensible.) It's a useful function (well, actually a macro in C world rather than a function). I've often wanted signbit in Python-land, usually in circumstances where I do care about the sign of zero, but it's at least easily (albeit not very efficiently) spelled as math.copysign(1.0, x) < 0.0.
Guessing that you meant math.tgamma here? Python's math.lgamma exactly matches C99's math.lgamma.
C has its own history that led to the C99 function for 𝛤 being called tgamma rather than gamma: once upon a time, gamma computed the log of the absolute value of the mathematical Gamma function. The t in tgamma is there for disambiguation (meaning "true gamma"). Outside of the context of C, tgamma is a non-obvious name for something that computes the Gamma function. Since Python doesn't have the same historical baggage as C here, I think gamma was the right name to use for the Python function.
picnixz commented on Jun 23, 2025
Oups, yes my bad. I meant tgamma not lgamma.
picnixz commented on Jun 23, 2025
rhettinger commented on Jun 23, 2025
+1 for signbit. The others seem like arcana that would clutter the math module with tools that people won't use in practice.
picnixz commented on Jun 23, 2025
signbit seems to have good support. I also quickly checked with numpy, and there is numpy.signbit however numpy.fpclassify or np.fdim do not exist. np.fmax and np.fmin do exist though but let's decide it later.
I think remquo and isunordered are really too obscure for the Python user. First, isunordered may be safe a few lines but a helper function that is better named would be better. As for remquo, it doesn't exist in numpy and neither do scalbn nor logb (and they can really be confused with log in base b...).
I'll work tomorrow on adding signbit.
skirpichev commented on Jun 23, 2025
I assume we don't consider anything outside of the C11? If not - e.g. rootn() (coming with C23) is good candidate.
I was thinking about exposing fenv.h, at least partially. Maybe to do this properly we should introduce context notion for floating-point math, just like the decimal module does: rounding modes, raise exceptions or not (see #133895), etc.
picnixz commented on Jun 23, 2025
For this issue, no. It was mainly about those defined in C99 (and likely the same as in C11, I don't remember if there are differences). For other functions, I think we should have a separate issue.
gh-135853: add `math.signbit` (#135877)
pythongh-135853: add `math.signbit` (python#135877)
gh-135853: add `math.fmax` and `math.fmin` (#135888)
picnixz commented on Jul 12, 2025
We now have all needed C99/C11 functions. Others are really too niche to be added and even numpy doesn't have them, meaning that they are likely not useful even for them.
pythongh-135853: add `math.signbit` (python#135877)
pythongh-135853: add `math.fmax` and `math.fmin` (python#135888)
pythongh-135853: add `math.fmax` and `math.fmin` (python#135888)
pythongh-135853: add `math.signbit` (python#135877)
pythongh-135853: add `math.fmax` and `math.fmin` (python#135888)
pythongh-135853: add `math.signbit` (python#135877)
pythongh-135853: add `math.fmax` and `math.fmin` (python#135888)