| ... | @@ -859,6 +859,27 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { | ... | @@ -859,6 +859,27 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 859 | return @bitCast(T, ux); | 859 | return @bitCast(T, ux); |
| 860 | } | 860 | } |
| 861 | | 861 | |
| | 862 | test "fmod, fmodf" { |
| | 863 | inline for ([_]type{ f32, f64 }) |T| { |
| | 864 | const nan_val = math.nan(T); |
| | 865 | const inf_val = math.inf(T); |
| | 866 | |
| | 867 | std.testing.expect(isNan(generic_fmod(T, nan_val, 1.0))); |
| | 868 | std.testing.expect(isNan(generic_fmod(T, 1.0, nan_val))); |
| | 869 | std.testing.expect(isNan(generic_fmod(T, inf_val, 1.0))); |
| | 870 | std.testing.expect(isNan(generic_fmod(T, 0.0, 0.0))); |
| | 871 | std.testing.expect(isNan(generic_fmod(T, 1.0, 0.0))); |
| | 872 | |
| | 873 | std.testing.expectEqual(@as(T, 0.0), generic_fmod(T, 0.0, 2.0)); |
| | 874 | std.testing.expectEqual(@as(T, -0.0), generic_fmod(T, -0.0, 2.0)); |
| | 875 | |
| | 876 | std.testing.expectEqual(@as(T, -2.0), generic_fmod(T, -32.0, 10.0)); |
| | 877 | std.testing.expectEqual(@as(T, -2.0), generic_fmod(T, -32.0, -10.0)); |
| | 878 | std.testing.expectEqual(@as(T, 2.0), generic_fmod(T, 32.0, 10.0)); |
| | 879 | std.testing.expectEqual(@as(T, 2.0), generic_fmod(T, 32.0, -10.0)); |
| | 880 | } |
| | 881 | } |
| | 882 | |
| 862 | // NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound | 883 | // NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound |
| 863 | // behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are | 884 | // behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are |
| 864 | // potentially some edge cases remaining that are not handled in the same way. | 885 | // potentially some edge cases remaining that are not handled in the same way. |