-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
Have math.isnormal() and, perhaps, math.issubnormal()? #132908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I once needed to know about whether a number is subnormal() so I would be happy to have it but... I think it's niche and For |
This is something more basic and is a part of libm.
Yes, it's essentially a free lunch.
I think we can check compiler conformance and if C23 support is missing - provide a simple replacement in terms of isfinite() & isnormal(). |
PR is ready to review: #132935 |
I suggest leaving these out until there is a demonstrated user need. Unless people actually need this (I never have), it becomes module clutter than gets in the way of finding "the good stuff". We shouldn't add cognitive loads (one more thing to learn and remember) unless we expect a payoff. |
If bugreport is a demonstration of "used needs" - here it is. SO example: https://stackoverflow.com/questions/59277521
On the other hand, people can expect this from the libm wrapper. This time, rather than reinventing the wheel - I filled this bugreport. |
I'm going to close this, on ground of Raymond's feedback. @tim-one ? |
Contrary to closing it, I'd like to see it expanded to include Alas, it looks like although "even Microsoft" supports I don't find Raymond's objection persuasive in this case. It's not like we're making them up - they're very widely implemented already (comes with being part of standard C), the names are bizarre enough that if's dead easy to find detailed docs with a web search, and they're not at all hard to understand. Indeed, the names are darned near self-explanatory Ironically, I would have used these things yesterday, while writing a saner Which I appreciate is more in the area of writing math libraries than end-user apps. I don't think they'll be widely used. But there's another kind of cognitive burden in trying to remember which near-universally supported math functions Python thinks are beneath its attention 😉. |
I was thinking about, but I don't see good arguments beyond "libm has it". After all, we don't have every
issubnormal() is a part of C23, which MSVC doesn't support yet. |
That "even Microsoft" has it means even they thought it was worth it 😉. Indeed, with
Why is that compelling to you for some minor libm functions, but poo-poo';ed for others?
And probably won't unless someone asks for them. Non-binary machines stil aren't really "a thing", so I don't expect anyone will. Suit yourself, but I see no consistency in adding some minor libm functions but not others. "Why not fpclassify too, then?" was my first thought when seeing this report's title. They all make immediate sense for the fp format virtually everyone in the world uses. |
And vice versa. These interfaces looks non-orthogonal. Maybe it does make sense for C to speedup something somewhere... Though, my search over Github shows two major cases: 1) serialization of floats, 2) misuse of the fpcassify() API, where it could be replaced by one of isfoo(). And very rare cases of 2), when it's impossible. On another hand, maybe we should prefer
This example was somewhat random. But there is a signbit(), for example. It's easy to grep out it's replacements with copysign() in Lib/test/. |
Aren't we missing
|
The C99+ Annex G doesn't define anything like that. Though, it also doesn't include isfinite (or isinf/isnan). But it says:
That's exactly - Python's isfinite/isinf. The isnan() in Python looks as an extension. But I doubt that isnormal() for complex numbers can be defined like that. |
Great, different programming languages disagree on this:
public static bool IsNormal(Complex value)
{
// much as IsFinite requires both part to be finite, we require both
// part to be "normal" (finite, non-zero, and non-subnormal) to be true
return double.IsNormal(value.m_real) && ((value.m_imaginary == 0.0) || double.IsNormal(value.m_imaginary));
}
public static bool IsSubnormal(Complex value)
{
// much as IsInfinite allows either part to be infinite, we allow either
// part to be "subnormal" (finite, non-zero, and non-normal) to be true
return double.IsSubnormal(value.m_real) || double.IsSubnormal(value.m_imaginary);
}
/// True if this value is normal.
///
/// A complex number is normal if it is finite and *either* the real or
/// imaginary component is normal. A floating-point number representing
/// one of the components is normal if its exponent allows a full-precision
/// representation.
///
/// See also `.isFinite`, `.isSubnormal` and `.isZero`.
@_transparent
public var isNormal: Bool {
isFinite && (x.isNormal || y.isNormal)
}
/// True if this value is subnormal.
///
/// A complex number is subnormal if it is finite, not normal, and not zero.
/// When the result of a computation is subnormal, underflow has occurred and
/// the result generally does not have full precision.
///
/// See also `.isFinite`, `.isNormal` and `.isZero`.
@_transparent
public var isSubnormal: Bool {
isFinite && !isNormal && !isZero
} |
No doubts, you can define such notions. But note, that your definitions are different. The C99 standard rationale shows arguments for isinf/isnan, e.g.: Which arguments for using either definition of isnormal() for complex numbers? Is this useful? Why? M$ version is especially odd as asymmetrical wrt components. |
$ python -m timeit -s "a = 2+0j; b = 5e-308+5e-308j" "a * b"
5000000 loops, best of 5: 49.1 nsec per loop
$ python -m timeit -s "a = 2+0j; b = 5e-308+5e-324j" "a * b"
5000000 loops, best of 5: 88.3 nsec per loop
$ python -m timeit -s "a = 2+0j; b = 5e-324+5e-324j" "a * b"
2000000 loops, best of 5: 124 nsec per loop
>>> (5e-308+5e-308j) * 1e308
(5+5j)
>>> (5e-308+5e-324j) * 1e308
(5+4.9406564584124655e-16j)
>>> (5e-324+5e-324j) * 1e308
(4.9406564584124655e-16+4.9406564584124655e-16j)
Do you see an argument for the other definition? Or should we give that a different name? |
Sorry, could be elaborate your "performance" and "accuracy" arguments? |
I'm mostly trying to compare it with the reasons for having
So, raising an error in these cases using |
Yes, but I don't see yet arguments for a concrete |
Maybe we should discuss this on Discourse? |
Feel free to do so . |
Uh oh!
There was an error while loading. Please reload this page.
Feature or enhancement
Proposal:
Of course, these functions can be emulated in pure-Python.
On another hand, people can reasonably expect these classifiers as "The math module consists mostly of thin wrappers around the platform C math library functions." (c)
isnormal()
was in libm since C99 andissubnormal()
- since C23.Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response
Linked PRs
The text was updated successfully, but these errors were encountered: