authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-04-20 15:44:21+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-04-20 15:44:21+02:00
loga4e2539b09dcf73ccf1bd57541b3b6c267ca96c1
tree58fcf17324185f5fbe3d7c573ac6c6f7a85c1437
parentfcfe25710bcc7c3c8ccd23bbad32c02ae6df7c40

c: Implement fmax and fmaxf


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

lib/std/special/c.zig+29
...@@ -909,6 +909,35 @@ test "fmin, fminf" {...@@ -909,6 +909,35 @@ test "fmin, fminf" {
909 }909 }
910}910}
911911
912fn generic_fmax(comptime T: type, x: T, y: T) T {
913 if (isNan(x))
914 return y;
915 if (isNan(y))
916 return x;
917 return if (x < y) y else x;
918}
919
920export fn fmaxf(x: f32, y: f32) callconv(.C) f32 {
921 return generic_fmax(f32, x, y);
922}
923
924export fn fmax(x: f64, y: f64) callconv(.C) f64 {
925 return generic_fmax(f64, x, y);
926}
927
928test "fmax, fmaxf" {
929 inline for ([_]type{ f32, f64 }) |T| {
930 const nan_val = math.nan(T);
931
932 std.testing.expect(isNan(generic_fmax(T, nan_val, nan_val)));
933 std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, nan_val, 1.0));
934 std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, 1.0, nan_val));
935
936 std.testing.expectEqual(@as(T, 10.0), generic_fmax(T, 1.0, 10.0));
937 std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, 1.0, -1.0));
938 }
939}
940
912// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound941// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound
913// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are942// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are
914// potentially some edge cases remaining that are not handled in the same way.943// potentially some edge cases remaining that are not handled in the same way.