authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-04-20 15:43:46+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-04-20 15:43:46+02:00
logfcfe25710bcc7c3c8ccd23bbad32c02ae6df7c40
tree9fef8b32e05a25e4df14555bba8c286a08edbcbb
parentc7c77fb1b049070f9bf4009a36c9e563783fab62

c: Implement fmin and fminf


1 files changed, 29 insertions(+), 0 deletions(-)

lib/std/special/c.zig+29
...@@ -880,6 +880,35 @@ test "fmod, fmodf" {...@@ -880,6 +880,35 @@ test "fmod, fmodf" {
880 }880 }
881}881}
882882
883fn generic_fmin(comptime T: type, x: T, y: T) T {
884 if (isNan(x))
885 return y;
886 if (isNan(y))
887 return x;
888 return if (x < y) x else y;
889}
890
891export fn fminf(x: f32, y: f32) callconv(.C) f32 {
892 return generic_fmin(f32, x, y);
893}
894
895export fn fmin(x: f64, y: f64) callconv(.C) f64 {
896 return generic_fmin(f64, x, y);
897}
898
899test "fmin, fminf" {
900 inline for ([_]type{ f32, f64 }) |T| {
901 const nan_val = math.nan(T);
902
903 std.testing.expect(isNan(generic_fmin(T, nan_val, nan_val)));
904 std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, nan_val, 1.0));
905 std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, 1.0, nan_val));
906
907 std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, 1.0, 10.0));
908 std.testing.expectEqual(@as(T, -1.0), generic_fmin(T, 1.0, -1.0));
909 }
910}
911
883// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound912// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound
884// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are913// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are
885// potentially some edge cases remaining that are not handled in the same way.914// potentially some edge cases remaining that are not handled in the same way.