| ... | ... | @@ -239,7 +239,7 @@ export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) isiz |
| 239 | 239 | return 0; |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | | test "test_memcmp" { |
| 242 | test "memcmp" { |
| 243 | 243 | const base_arr = &[_]u8{ 1, 1, 1 }; |
| 244 | 244 | const arr1 = &[_]u8{ 1, 1, 1 }; |
| 245 | 245 | const arr2 = &[_]u8{ 1, 0, 1 }; |
| ... | ... | @@ -263,7 +263,7 @@ export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) c |
| 263 | 263 | return 0; |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | | test "test_bcmp" { |
| 266 | test "bcmp" { |
| 267 | 267 | const base_arr = &[_]u8{ 1, 1, 1 }; |
| 268 | 268 | const arr1 = &[_]u8{ 1, 1, 1 }; |
| 269 | 269 | const arr2 = &[_]u8{ 1, 0, 1 }; |
| ... | ... | @@ -859,6 +859,85 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 859 | 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 | |
| 883 | fn 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 | |
| 891 | export fn fminf(x: f32, y: f32) callconv(.C) f32 { |
| 892 | return generic_fmin(f32, x, y); |
| 893 | } |
| 894 | |
| 895 | export fn fmin(x: f64, y: f64) callconv(.C) f64 { |
| 896 | return generic_fmin(f64, x, y); |
| 897 | } |
| 898 | |
| 899 | test "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 | |
| 912 | fn 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 | |
| 920 | export fn fmaxf(x: f32, y: f32) callconv(.C) f32 { |
| 921 | return generic_fmax(f32, x, y); |
| 922 | } |
| 923 | |
| 924 | export fn fmax(x: f64, y: f64) callconv(.C) f64 { |
| 925 | return generic_fmax(f64, x, y); |
| 926 | } |
| 927 | |
| 928 | test "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 | |
| 862 | 941 | // NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound |
| 863 | 942 | // behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are |
| 864 | 943 | // potentially some edge cases remaining that are not handled in the same way. |
| ... | ... | @@ -1017,8 +1096,8 @@ test "sqrt special" { |
| 1017 | 1096 | std.testing.expect(std.math.isPositiveInf(sqrt(std.math.inf(f64)))); |
| 1018 | 1097 | std.testing.expect(sqrt(0.0) == 0.0); |
| 1019 | 1098 | std.testing.expect(sqrt(-0.0) == -0.0); |
| 1020 | | std.testing.expect(std.math.isNan(sqrt(-1.0))); |
| 1021 | | std.testing.expect(std.math.isNan(sqrt(std.math.nan(f64)))); |
| 1099 | std.testing.expect(isNan(sqrt(-1.0))); |
| 1100 | std.testing.expect(isNan(sqrt(std.math.nan(f64)))); |
| 1022 | 1101 | } |
| 1023 | 1102 | |
| 1024 | 1103 | export fn sqrtf(x: f32) f32 { |
| ... | ... | @@ -1122,6 +1201,6 @@ test "sqrtf special" { |
| 1122 | 1201 | std.testing.expect(std.math.isPositiveInf(sqrtf(std.math.inf(f32)))); |
| 1123 | 1202 | std.testing.expect(sqrtf(0.0) == 0.0); |
| 1124 | 1203 | std.testing.expect(sqrtf(-0.0) == -0.0); |
| 1125 | | std.testing.expect(std.math.isNan(sqrtf(-1.0))); |
| 1126 | | std.testing.expect(std.math.isNan(sqrtf(std.math.nan(f32)))); |
| 1204 | std.testing.expect(isNan(sqrtf(-1.0))); |
| 1205 | std.testing.expect(isNan(sqrtf(std.math.nan(f32)))); |
| 1127 | 1206 | } |