authorgravatar for hi@mihaelm.commihael <hi@mihaelm.com> 2026-03-18 23:02:53+01:00
committergravatar for hi@mihaelm.commihael <hi@mihaelm.com> 2026-04-02 23:54:19+02:00
log521a093334eb92b4fd2430b9018ed94b912857a8
tree7aa1be7b8c66715c851e74cc93b315c0dfe4e0cb
parentdcffee067290c03f89c5afcacab1ba543ee28e7c
signaturebadge-check Signed by SSH key SHA256:aoFoShdYLdrqMichqKXSSieTKUfACUIDJHsKc4V2tQg

`libzigc/math`: Implement `frexpf`

The `frexp` implementation was generalized so it can be used for `f32` and `c_longdouble` types as well. The changes were tested by running: ``` $ ./build/stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib $ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=frexp -fqemu -fwasmtime --summary line Build Summary: 737/737 steps succeeded $ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=frexpf -fqemu -fwasmtime --summary line Build Summary: 369/369 steps succeeded ```

6 files changed, 11 insertions(+), 41 deletions(-)

lib/c/math.zig+11-2
......@@ -36,6 +36,7 @@ comptime {
3636
3737 if (builtin.target.isMinGW() or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
3838 symbol(&coshf, "coshf");
39 symbol(&frexpf, "frexpf");
3940 symbol(&hypotf, "hypotf");
4041 symbol(&hypotl, "hypotl");
4142 symbol(&modff, "modff");
......@@ -162,7 +163,7 @@ fn fdim(x: f64, y: f64) callconv(.c) f64 {
162163 return 0;
163164}
164165
165fn frexp(x: f64, e: *c_int) callconv(.c) f64 {
166fn frexpGeneric(comptime T: type, x: T, e: *c_int) T {
166167 // libc expects `*e` to be unspecified in this case; an unspecified C value
167168 // should be a valid value of the relevant type, yet Zig's std
168169 // implementation sets it to `undefined` -- which can even be nonsense
......@@ -170,7 +171,7 @@ fn frexp(x: f64, e: *c_int) callconv(.c) f64 {
170171 // int value in Zig -- a zero.
171172 //
172173 // This mirrors the handling of infinities, where libc also expects
173 // unspecified for the value `*e` and Zig std sets it to a zero.
174 // unspecified for the value of `*e` and Zig std sets it to a zero.
174175 if (math.isNan(x)) {
175176 e.* = 0;
176177 return x;
......@@ -181,6 +182,14 @@ fn frexp(x: f64, e: *c_int) callconv(.c) f64 {
181182 return r.significand;
182183}
183184
185fn frexp(x: f64, e: *c_int) callconv(.c) f64 {
186 return frexpGeneric(f64, x, e);
187}
188
189fn frexpf(x: f32, e: *c_int) callconv(.c) f32 {
190 return frexpGeneric(f32, x, e);
191}
192
184193fn hypot(x: f64, y: f64) callconv(.c) f64 {
185194 return math.hypot(x, y);
186195}
lib/libc/mingw/math/frexpf.c deleted-13
......@@ -1,13 +0,0 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6extern double __cdecl frexp(double _X,int *_Y);
7
8float frexpf (float, int *);
9float frexpf (float x, int *expn)
10{
11 return (float)frexp(x, expn);
12}
13
lib/libc/musl/src/math/frexpf.c deleted-23
......@@ -1,23 +0,0 @@
1#include <math.h>
2#include <stdint.h>
3
4float frexpf(float x, int *e)
5{
6 union { float f; uint32_t i; } y = { x };
7 int ee = y.i>>23 & 0xff;
8
9 if (!ee) {
10 if (x) {
11 x = frexpf(x*0x1p64, e);
12 *e -= 64;
13 } else *e = 0;
14 return x;
15 } else if (ee == 0xff) {
16 return x;
17 }
18
19 *e = ee - 0x7e;
20 y.i &= 0x807ffffful;
21 y.i |= 0x3f000000ul;
22 return y.f;
23}
src/libs/mingw.zig-1
......@@ -613,7 +613,6 @@ const mingw32_generic_src = [_][]const u8{
613613 "math" ++ path.sep_str ++ "fpclassify.c",
614614 "math" ++ path.sep_str ++ "fpclassifyf.c",
615615 "math" ++ path.sep_str ++ "fpclassifyl.c",
616 "math" ++ path.sep_str ++ "frexpf.c",
617616 "math" ++ path.sep_str ++ "frexpl.c",
618617 "math" ++ path.sep_str ++ "ldexpf.c",
619618 "math" ++ path.sep_str ++ "lgamma.c",
src/libs/musl.zig-1
......@@ -839,7 +839,6 @@ const src_files = [_][]const u8{
839839 "musl/src/math/__fpclassify.c",
840840 "musl/src/math/__fpclassifyf.c",
841841 "musl/src/math/__fpclassifyl.c",
842 "musl/src/math/frexpf.c",
843842 "musl/src/math/frexpl.c",
844843 "musl/src/math/i386/acosl.s",
845844 "musl/src/math/i386/asinf.s",
src/libs/wasi_libc.zig-1
......@@ -701,7 +701,6 @@ const libc_top_half_src_files = [_][]const u8{
701701 "musl/src/math/finitef.c",
702702 "musl/src/math/fma.c",
703703 "musl/src/math/fmaf.c",
704 "musl/src/math/frexpf.c",
705704 "musl/src/math/frexpl.c",
706705 "musl/src/math/ilogb.c",
707706 "musl/src/math/ilogbf.c",