authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-04-20 19:54:16+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-04-20 19:54:16+03:00
log2ca26ffde7342f7b676507452df75fbec545f650
treeb2a8cb3a5e735fad62b4f458af4489676d5ddb6f
parentd64c76e8f1faf493d5fa6f3c0d9324f05f99d68f
parenta5a3ad5e10a6c5aa88af5eaf0170c5a15c9aad90
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8582 from LemonBoy/more-libc-impl

Improve the libc implementation

1 files changed, 85 insertions(+), 6 deletions(-)

lib/std/special/c.zig+85-6
...@@ -239,7 +239,7 @@ export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) isiz...@@ -239,7 +239,7 @@ export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) isiz
239 return 0;239 return 0;
240}240}
241241
242test "test_memcmp" {242test "memcmp" {
243 const base_arr = &[_]u8{ 1, 1, 1 };243 const base_arr = &[_]u8{ 1, 1, 1 };
244 const arr1 = &[_]u8{ 1, 1, 1 };244 const arr1 = &[_]u8{ 1, 1, 1 };
245 const arr2 = &[_]u8{ 1, 0, 1 };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,7 +263,7 @@ export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) c
263 return 0;263 return 0;
264}264}
265265
266test "test_bcmp" {266test "bcmp" {
267 const base_arr = &[_]u8{ 1, 1, 1 };267 const base_arr = &[_]u8{ 1, 1, 1 };
268 const arr1 = &[_]u8{ 1, 1, 1 };268 const arr1 = &[_]u8{ 1, 1, 1 };
269 const arr2 = &[_]u8{ 1, 0, 1 };269 const arr2 = &[_]u8{ 1, 0, 1 };
...@@ -859,6 +859,85 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -859,6 +859,85 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
859 return @bitCast(T, ux);859 return @bitCast(T, ux);
860}860}
861861
862test "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
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
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
862// 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
863// 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
864// 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.
...@@ -1017,8 +1096,8 @@ test "sqrt special" {...@@ -1017,8 +1096,8 @@ test "sqrt special" {
1017 std.testing.expect(std.math.isPositiveInf(sqrt(std.math.inf(f64))));1096 std.testing.expect(std.math.isPositiveInf(sqrt(std.math.inf(f64))));
1018 std.testing.expect(sqrt(0.0) == 0.0);1097 std.testing.expect(sqrt(0.0) == 0.0);
1019 std.testing.expect(sqrt(-0.0) == -0.0);1098 std.testing.expect(sqrt(-0.0) == -0.0);
1020 std.testing.expect(std.math.isNan(sqrt(-1.0)));1099 std.testing.expect(isNan(sqrt(-1.0)));
1021 std.testing.expect(std.math.isNan(sqrt(std.math.nan(f64))));1100 std.testing.expect(isNan(sqrt(std.math.nan(f64))));
1022}1101}
10231102
1024export fn sqrtf(x: f32) f32 {1103export fn sqrtf(x: f32) f32 {
...@@ -1122,6 +1201,6 @@ test "sqrtf special" {...@@ -1122,6 +1201,6 @@ test "sqrtf special" {
1122 std.testing.expect(std.math.isPositiveInf(sqrtf(std.math.inf(f32))));1201 std.testing.expect(std.math.isPositiveInf(sqrtf(std.math.inf(f32))));
1123 std.testing.expect(sqrtf(0.0) == 0.0);1202 std.testing.expect(sqrtf(0.0) == 0.0);
1124 std.testing.expect(sqrtf(-0.0) == -0.0);1203 std.testing.expect(sqrtf(-0.0) == -0.0);
1125 std.testing.expect(std.math.isNan(sqrtf(-1.0)));1204 std.testing.expect(isNan(sqrtf(-1.0)));
1126 std.testing.expect(std.math.isNan(sqrtf(std.math.nan(f32))));1205 std.testing.expect(isNan(sqrtf(std.math.nan(f32))));
1127}1206}