Skip to content

math.pow: add f16, f80, f128, c_longdouble support #23631

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

vilhelmbergsoe
Copy link

Removes the compile error restricting math.pow to f32/f64, allowing its use with f16, f80, f128, and c_longdouble.

Adds a compile error when T is comptime_float. The current pow implementation relies on concrete float properties (e.g., bit layout via @typeInfo(T).float.bits) which aren't available for comptime_float as far as I can tell.

There may be other ways to handle this, but this approach at least adds support for the concrete floating point types :)

Partly fixes: #23602

@alexrp
Copy link
Member

alexrp commented Apr 20, 2025

Adds a compile error when T is comptime_float. The current pow implementation relies on concrete float properties (e.g., bit layout via @typeInfo(T).float.bits) which aren't available for comptime_float as far as I can tell.

I believe the current thinking is that comptime_float should mostly behave as f128, except for NaNs, or something like that. @mlugg can you confirm?

Generalizes math.pow to accept f16, f80, and f128 types.
Comment on lines +210 to +211
try expect(math.approxEqAbs(f16, pow(f16, 37.45, 3.3), 155736.7160616, epsilon16));
try expect(math.approxEqAbs(f16, pow(f16, 89.123, 3.3), 2722490.231436, epsilon16));
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be a dumb question, but shouldn't these two result in +inf with the results being way over the maximum value of f16?

Copy link
Author

Choose a reason for hiding this comment

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

Good catch! You're right, the expected result for f16 should be +inf.

The test likely passed because the large literal 155736.7... also overflows to +inf when cast to f16, causing approxEqAbs to hit the x == y fast path.

Maybe it's clearer to test explicitly with == math.inf(f16) in this overflow case?

Copy link
Contributor

@fardragon fardragon Apr 23, 2025

Choose a reason for hiding this comment

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

Oh, I guess that's true. I've mixed up inf comparison and NaN comparison in my mind, but you're right, that's probably what's happening here. But I agree that explicitly comparing to inf or even using math.isInf would be more clear here. At least in my opinion.

@Empika1
Copy link

Empika1 commented Apr 26, 2025

It seems that comptime_float should behave like f128 but where NaN and inf result in compile errors. With that in mind, it seems like, when comptime_floats are passed in, you could just cast them to f128s, and if the result is NaN or inf, throw a @CompileError(). Are there any problems with that approach that I'm missing?

@vilhelmbergsoe
Copy link
Author

Casting comptime_float inputs to f128 and then checking the result seems like the plan.

It seems that comptime_float should behave like f128 but where NaN and inf result in compile errors.

@Empika1 - Can you point to where you see this pattern? I wasn't able to find anything similar myself.

Still wondering if we should @compileError on both NaN and Inf results from the f128 cast, or only NaN?

If it's only NaN, perhaps the existing NaN handling within pow is sufficient, and we'd just need the conditional cast to f128?

@alexrp / @mlugg, could you clarify the intended behavior?

@alexrp
Copy link
Member

alexrp commented May 2, 2025

#21205 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

std.math.pow doesn't support f16, f80, f128, c_longdouble or comptime_float
5 participants