authorgravatar for 27766253+JanikkinaJ@users.noreply.github.com.kineye <27766253+JanikkinaJ@users.noreply.github.com.> 2026-02-07 16:09:29+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-12 21:42:38-08:00
logf36d0573cd0f80b271b9f07a7215fa237d14ae9a
tree2075d0d2e778248953a853c5a6dd352724e78a6e
parent5132d78e8385cbadc888275761258a1fca27b6f0

zig libc: add rint


4 files changed, 57 insertions(+), 47 deletions(-)

lib/c/math.zig+57
...@@ -56,6 +56,7 @@ comptime {...@@ -56,6 +56,7 @@ comptime {
56 if (builtin.target.isMuslLibC()) {56 if (builtin.target.isMuslLibC()) {
57 symbol(&copysignf, "copysignf");57 symbol(&copysignf, "copysignf");
58 symbol(&copysign, "copysign");58 symbol(&copysign, "copysign");
59 symbol(&rint, "rint");
59 }60 }
60 symbol(&copysignl, "copysignl");61 symbol(&copysignl, "copysignl");
61}62}
...@@ -158,3 +159,59 @@ fn pow10(x: f64) callconv(.c) f64 {...@@ -158,3 +159,59 @@ fn pow10(x: f64) callconv(.c) f64 {
158fn pow10f(x: f32) callconv(.c) f32 {159fn pow10f(x: f32) callconv(.c) f32 {
159 return exp10f(x);160 return exp10f(x);
160}161}
162
163fn rint(x: f64) callconv(.c) f64 {
164 const toint: f64 = 1.0 / @as(f64, std.math.floatEps(f64));
165 const a: u64 = @bitCast(x);
166 const e = a >> 52 & 0x7ff;
167 const s = a >> 63;
168 var y: f64 = undefined;
169
170 if (e >= 0x3ff + 52) {
171 return x;
172 }
173 if (s == 1) {
174 y = x - toint + toint;
175 } else {
176 y = x + toint - toint;
177 }
178 if (y == 0) {
179 return if (s == 1) -0.0 else 0;
180 }
181 return y;
182}
183
184test "rint" {
185 // Positive numbers round correctly
186 try std.testing.expectEqual(@as(f64, 42.0), rint(42.2));
187 try std.testing.expectEqual(@as(f64, 42.0), rint(41.8));
188
189 // Negative numbers round correctly
190 try std.testing.expectEqual(@as(f64, -6.0), rint(-5.9));
191 try std.testing.expectEqual(@as(f64, -6.0), rint(-6.1));
192
193 // No rounding needed test
194 try std.testing.expectEqual(@as(f64, 5.0), rint(5.0));
195 try std.testing.expectEqual(@as(f64, -10.0), rint(-10.0));
196 try std.testing.expectEqual(@as(f64, 0.0), rint(0.0));
197
198 // Very large numbers return unchanged
199 const large: f64 = 9007199254740992.0; // 2^53
200 try std.testing.expectEqual(large, rint(large));
201 try std.testing.expectEqual(-large, rint(-large));
202
203 // Small positive numbers round to zero
204 const pos_result = rint(0.3);
205 try std.testing.expectEqual(@as(f64, 0.0), pos_result);
206 try std.testing.expect(@as(u64, @bitCast(pos_result)) == 0);
207
208 // Small negative numbers round to negative zero
209 const neg_result = rint(-0.3);
210 try std.testing.expectEqual(@as(f64, 0.0), neg_result);
211 const bits: u64 = @bitCast(neg_result);
212 try std.testing.expect((bits >> 63) == 1);
213
214 // Exact half rounds to nearest even (banker's rounding)
215 try std.testing.expectEqual(@as(f64, 2.0), rint(2.5));
216 try std.testing.expectEqual(@as(f64, 4.0), rint(3.5));
217}
lib/libc/musl/src/math/rint.c deleted-28
...@@ -1,28 +0,0 @@
1#include <float.h>
2#include <math.h>
3#include <stdint.h>
4
5#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
6#define EPS DBL_EPSILON
7#elif FLT_EVAL_METHOD==2
8#define EPS LDBL_EPSILON
9#endif
10static const double_t toint = 1/EPS;
11
12double rint(double x)
13{
14 union {double f; uint64_t i;} u = {x};
15 int e = u.i>>52 & 0x7ff;
16 int s = u.i>>63;
17 double_t y;
18
19 if (e >= 0x3ff+52)
20 return x;
21 if (s)
22 y = x - toint + toint;
23 else
24 y = x + toint - toint;
25 if (y == 0)
26 return s ? -0.0 : 0;
27 return y;
28}
lib/libc/musl/src/math/s390x/rint.c deleted-15
...@@ -1,15 +0,0 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double rint(double x)
6{
7 __asm__ ("fidbr %0, 0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../rint.c"
14
15#endif
src/libs/musl.zig-4
...@@ -797,7 +797,6 @@ const src_files = [_][]const u8{...@@ -797,7 +797,6 @@ const src_files = [_][]const u8{
797 "musl/src/math/aarch64/lroundf.c",797 "musl/src/math/aarch64/lroundf.c",
798 "musl/src/math/aarch64/nearbyint.c",798 "musl/src/math/aarch64/nearbyint.c",
799 "musl/src/math/aarch64/nearbyintf.c",799 "musl/src/math/aarch64/nearbyintf.c",
800 "musl/src/math/aarch64/rint.c",
801 "musl/src/math/aarch64/rintf.c",800 "musl/src/math/aarch64/rintf.c",
802 "musl/src/math/acosf.c",801 "musl/src/math/acosf.c",
803 "musl/src/math/acosh.c",802 "musl/src/math/acosh.c",
...@@ -887,7 +886,6 @@ const src_files = [_][]const u8{...@@ -887,7 +886,6 @@ const src_files = [_][]const u8{
887 "musl/src/math/i386/remquof.s",886 "musl/src/math/i386/remquof.s",
888 "musl/src/math/i386/remquol.s",887 "musl/src/math/i386/remquol.s",
889 "musl/src/math/i386/remquo.s",888 "musl/src/math/i386/remquo.s",
890 "musl/src/math/i386/rint.c",
891 "musl/src/math/i386/rintf.c",889 "musl/src/math/i386/rintf.c",
892 "musl/src/math/i386/rintl.c",890 "musl/src/math/i386/rintl.c",
893 "musl/src/math/i386/scalblnf.s",891 "musl/src/math/i386/scalblnf.s",
...@@ -981,7 +979,6 @@ const src_files = [_][]const u8{...@@ -981,7 +979,6 @@ const src_files = [_][]const u8{
981 "musl/src/math/remquo.c",979 "musl/src/math/remquo.c",
982 "musl/src/math/remquof.c",980 "musl/src/math/remquof.c",
983 "musl/src/math/remquol.c",981 "musl/src/math/remquol.c",
984 "musl/src/math/rint.c",
985 "musl/src/math/rintf.c",982 "musl/src/math/rintf.c",
986 "musl/src/math/rintl.c",983 "musl/src/math/rintl.c",
987 "musl/src/math/riscv32/fma.c",984 "musl/src/math/riscv32/fma.c",
...@@ -993,7 +990,6 @@ const src_files = [_][]const u8{...@@ -993,7 +990,6 @@ const src_files = [_][]const u8{
993 "musl/src/math/s390x/nearbyint.c",990 "musl/src/math/s390x/nearbyint.c",
994 "musl/src/math/s390x/nearbyintf.c",991 "musl/src/math/s390x/nearbyintf.c",
995 "musl/src/math/s390x/nearbyintl.c",992 "musl/src/math/s390x/nearbyintl.c",
996 "musl/src/math/s390x/rint.c",
997 "musl/src/math/s390x/rintf.c",993 "musl/src/math/s390x/rintf.c",
998 "musl/src/math/s390x/rintl.c",994 "musl/src/math/s390x/rintl.c",
999 "musl/src/math/scalb.c",995 "musl/src/math/scalb.c",