Skip to content

Rework std.math.{order, Order}, and fix illegal behavior for NaN values with total ordering#23291

Closed
SeanTUT wants to merge 6 commits intoziglang:masterfrom
SeanTUT:order-patch
Closed

Rework std.math.{order, Order}, and fix illegal behavior for NaN values with total ordering#23291
SeanTUT wants to merge 6 commits intoziglang:masterfrom
SeanTUT:order-patch

Conversation

@SeanTUT
Copy link
Copy Markdown
Contributor

@SeanTUT SeanTUT commented Mar 18, 2025

  • Moved the implementation of std.math.order/std.math.Order into a new file (std/math/order.zig)
  • Floats use total ordering, eliminating the possibility of reaching unreachable code in std.math.order (The previous implementation would cause illegal behavior any time one of the operands was nan)
  • .lt, .eq, and .gt now have vales of -1, 0, and 1 respectively, allowing for some optimizations in ordering integers inverting orderings
  • std.mem.order now utilizes std.math.Order.differ instead of manually implementing the functionality
  • Modified up some existing tests to use std.testing.expectEqual instead of std.testing.expect when appropriate
  • Added a doctest to std.math.order, and a test on total ordering for floats

SeanTUT and others added 4 commits March 18, 2025 12:19
- Moved implementations of `std.math.order` and `std.math.Order` into
  their own file (lib/std/math/order.zig)
- Floats use total ordering, eliminating the possibility of reaching unreachable code in `std.math.order`
- `.lt`, `.eq`, and `.gt` now have vales of `-1`, `0`, and `1`
  respectively, allowing for some optimizations in ordering integers inverting orderings
- `std.mem.order` now utilizes `std.math.Order.differ` instead of
  manually implementing the functionality
- Modified up some existing tests to use `std.testing.expectEqual`
  instead of `std.testing.expect` when appropriate
@SeanTUT
Copy link
Copy Markdown
Contributor Author

SeanTUT commented Mar 18, 2025

To clarify, this is not a breaking change. The only change in behavior is that NaN values are ordered according to IEEE-754 total ordering (whereas ordering NaN values previously resulted in illegal behavior)

@SeanTUT
Copy link
Copy Markdown
Contributor Author

SeanTUT commented Mar 18, 2025

I'm seeing some strange behavior in these CI failures. The error message claims that Order has no tag with a value of 0, when it in fact does (Order.eq)

Comment thread lib/std/math/order.zig Outdated
const T = @TypeOf(lhs, rhs);
switch (@typeInfo(T)) {
.int, .comptime_int => {
return @enumFromInt(@as(i2, @intFromBool(lhs > rhs)) - @intFromBool(lhs < rhs));
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 can fix the errors by changing this back to the original implementation of std.math.order, but the fact that the error message is incorrect here is concerning

@SeanTUT
Copy link
Copy Markdown
Contributor Author

SeanTUT commented Mar 18, 2025

After some testing, I have found that this bug occurs on the stage2 compiler when using @enumFromInt at comptime with small enums. I will spend some time experimenting with this to find out the specifics and file an issue. Until I get more info on the bug, I am going to put a hold on this.

SeanTUT added 2 commits March 18, 2025 17:21
In math/order.zig, cast the results of the comparison to i8 before
subtracting. This sidesteps the discovered bug.
This test was intended for investigating a compiler bug which will be
looked into seperately
@SeanTUT
Copy link
Copy Markdown
Contributor Author

SeanTUT commented Mar 18, 2025

I have tweaked the code to sidestep the previously mentioned bug, but I will continue to look into this.

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.

1 participant