zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 7f6eab270493592d4c3e5788dfcb34fdbca80539 (tree)
parent ecea8cc16d783518d38c1022278336b422215232
Author: GasInfinity <me@gasinfinity.dev>
Date:   Thu,  8 Jan 2026 13:38:40 +0100

feat(libzigc): add `nan`, `nanf`, `nanl` and `bsearch`

* also remove musl implementation

Diffstat:
Mlib/c/math.zig | 33+++++++++++++++++++++++++++++++++
Mlib/c/stdlib.zig | 45+++++++++++++++++++++++++++++++++++++++++++++
Dlib/libc/mingw/math/fp_consts.c | 20--------------------
Dlib/libc/mingw/math/fp_consts.h | 50--------------------------------------------------
Dlib/libc/mingw/math/fp_constsf.c | 22----------------------
Dlib/libc/mingw/math/fp_constsl.c | 25-------------------------
Dlib/libc/musl/src/math/nan.c | 6------
Dlib/libc/musl/src/math/nanf.c | 6------
Dlib/libc/musl/src/math/nanl.c | 6------
Dlib/libc/musl/src/stdlib/bsearch.c | 20--------------------
Msrc/libs/mingw.zig | 3---
Msrc/libs/musl.zig | 4----
Msrc/libs/wasi_libc.zig | 4----
13 files changed, 78 insertions(+), 166 deletions(-)

diff --git a/lib/c/math.zig b/lib/c/math.zig @@ -10,6 +10,27 @@ comptime { @export(&isnanf, .{ .name = "__isnanf", .linkage = common.linkage, .visibility = common.visibility }); @export(&isnanl, .{ .name = "isnanl", .linkage = common.linkage, .visibility = common.visibility }); @export(&isnanl, .{ .name = "__isnanl", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&std.math.nan(f64), .{ .name = "__QNAN", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.snan(f64), .{ .name = "__SNAN", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.inf(f64), .{ .name = "__INF", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.floatTrueMin(f64), .{ .name = "__DENORM", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&std.math.nan(f32), .{ .name = "__QNANF", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.snan(f32), .{ .name = "__SNANF", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.inf(f32), .{ .name = "__INFF", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.floatTrueMin(f32), .{ .name = "__DENORMF", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&std.math.nan(c_longdouble), .{ .name = "__QNANL", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.snan(c_longdouble), .{ .name = "__SNANL", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.inf(c_longdouble), .{ .name = "__INFL", .linkage = common.linkage, .visibility = common.visibility }); + @export(&std.math.floatTrueMin(c_longdouble), .{ .name = "__DENORML", .linkage = common.linkage, .visibility = common.visibility }); + } + + if (builtin.target.isMinGW() or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { + @export(&nan, .{ .name = "nan", .linkage = common.linkage, .visibility = common.visibility }); + @export(&nanf, .{ .name = "nanf", .linkage = common.linkage, .visibility = common.visibility }); + @export(&nanl, .{ .name = "nanl", .linkage = common.linkage, .visibility = common.visibility }); } } @@ -24,3 +45,15 @@ fn isnanf(x: f32) callconv(.c) c_int { fn isnanl(x: c_longdouble) callconv(.c) c_int { return if (std.math.isNan(x)) 1 else 0; } + +fn nan(_: [*:0]const c_char) callconv(.c) f64 { + return std.math.nan(f64); +} + +fn nanf(_: [*:0]const c_char) callconv(.c) f32 { + return std.math.nan(f32); +} + +fn nanl(_: [*:0]const c_char) callconv(.c) c_longdouble { + return std.math.nan(c_longdouble); +} diff --git a/lib/c/stdlib.zig b/lib/c/stdlib.zig @@ -18,6 +18,8 @@ comptime { @export(&qsort_r, .{ .name = "qsort_r", .linkage = common.linkage, .visibility = common.visibility }); @export(&qsort, .{ .name = "qsort", .linkage = common.linkage, .visibility = common.visibility }); + + @export(&bsearch, .{ .name = "bsearch", .linkage = common.linkage, .visibility = common.visibility }); } } @@ -95,6 +97,26 @@ fn qsort(base: *anyopaque, n: usize, size: usize, compare: *const fn (a: *const }).wrap, @constCast(compare)); } +// NOTE: Despite its name, `bsearch` doesn't need to be implemented using binary search or make any complexity guarantee. +fn bsearch(key: *const anyopaque, base: *const anyopaque, n: usize, size: usize, compare: *const fn (a: *const anyopaque, b: *const anyopaque) callconv(.c) c_int) callconv(.c) ?*anyopaque { + const base_bytes: [*]const u8 = @ptrCast(base); + var low: usize = 0; + var high: usize = n; + + while (low < high) { + // Avoid overflowing in the midpoint calculation + const mid = low + (high - low) / 2; + const elem = &base_bytes[mid * size]; + + switch (std.math.order(compare(key, elem), 0)) { + .eq => return @constCast(elem), + .gt => low = mid + 1, + .lt => high = mid, + } + } + return null; +} + test abs { const val: c_int = -10; try std.testing.expectEqual(10, abs(val)); @@ -124,3 +146,26 @@ test lldiv { const expected: lldiv_t = .{ .quot = 1, .rem = 2 }; try std.testing.expectEqual(expected, lldiv(5, 3)); } + +test bsearch { + const Comparison = struct { + pub fn compare(a: *const anyopaque, b: *const anyopaque) callconv(.c) c_int { + const a_u16: *const u16 = @ptrCast(@alignCast(a)); + const b_u16: *const u16 = @ptrCast(@alignCast(b)); + + return switch (std.math.order(a_u16.*, b_u16.*)) { + .gt => 1, + .eq => 0, + .lt => -1, + }; + } + }; + + const items: []const u16 = &.{ 0, 5, 7, 9, 10, 200, 512, 768 }; + + try std.testing.expectEqual(@as(?*anyopaque, null), bsearch(&@as(u16, 2000), items.ptr, items.len, @sizeOf(u16), Comparison.compare)); + + for (items) |*value| { + try std.testing.expectEqual(@as(*const anyopaque, value), bsearch(value, items.ptr, items.len, @sizeOf(u16), Comparison.compare)); + } +} diff --git a/lib/libc/mingw/math/fp_consts.c b/lib/libc/mingw/math/fp_consts.c @@ -1,20 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include "fp_consts.h" -const union _ieee_rep __QNAN = { __DOUBLE_QNAN_REP }; -const union _ieee_rep __SNAN = { __DOUBLE_SNAN_REP }; -const union _ieee_rep __INF = { __DOUBLE_INF_REP }; -const union _ieee_rep __DENORM = { __DOUBLE_DENORM_REP }; - -/* ISO C99 */ -#undef nan -/* FIXME */ -double nan (const char *); -double nan (const char * tagp __attribute__((unused)) ) -{ - return __QNAN.double_val; -} - diff --git a/lib/libc/mingw/math/fp_consts.h b/lib/libc/mingw/math/fp_consts.h @@ -1,50 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#ifndef _FP_CONSTS_H -#define _FP_CONSTS_H - -/* -According to IEEE 754 a QNaN has exponent bits of all 1 values and -initial significand bit of 1. A SNaN has has an exponent of all 1 -values and initial significand bit of 0 (with one or more other -significand bits of 1). An Inf has significand of 0 and -exponent of all 1 values. A denormal value has all exponent bits of 0. -*/ - - -#define __DOUBLE_INF_REP { 0, 0, 0, 0x7ff0 } -#define __DOUBLE_QNAN_REP { 0, 0, 0, 0x7ff8 } -#define __DOUBLE_SNAN_REP { 0, 0, 0, 0x7ff0 } -#define __DOUBLE_DENORM_REP {1, 0, 0, 0} - -#define D_NAN_MASK 0x7ff0000000000000LL /* this will mask NaN's and Inf's */ - -#define __FLOAT_INF_REP { 0, 0x7f80 } -#define __FLOAT_QNAN_REP { 0, 0x7fc0 } -#define __FLOAT_SNAN_REP { 0, 0x7f80 } -#define __FLOAT_DENORM_REP {1,0} - -#define F_NAN_MASK 0x7f800000 - -/* - This assumes no implicit (hidden) bit in extended mode. - Padded to 96 bits - */ -#define __LONG_DOUBLE_INF_REP { 0, 0, 0, 0x8000, 0x7fff, 0 } -#define __LONG_DOUBLE_QNAN_REP { 0, 0, 0, 0xc000, 0x7fff, 0 } -#define __LONG_DOUBLE_SNAN_REP { 0, 0, 0, 0x8000, 0x7fff, 0 } -#define __LONG_DOUBLE_DENORM_REP {1, 0, 0, 0, 0, 0} - -union _ieee_rep -{ - unsigned short rep[6]; - float float_val; - double double_val; - long double ldouble_val; -}; - -#endif /* _FP_CONSTS_H */ - diff --git a/lib/libc/mingw/math/fp_constsf.c b/lib/libc/mingw/math/fp_constsf.c @@ -1,22 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include "fp_consts.h" - -const union _ieee_rep __QNANF = { __FLOAT_QNAN_REP }; -const union _ieee_rep __SNANF = { __FLOAT_SNAN_REP }; -const union _ieee_rep __INFF = { __FLOAT_INF_REP }; -const union _ieee_rep __DENORMF = { __FLOAT_DENORM_REP }; - -/* ISO C99 */ -#undef nanf -/* FIXME */ -float nanf(const char *); - -float nanf(const char * tagp __attribute__((unused)) ) -{ - return __QNANF.float_val; -} - diff --git a/lib/libc/mingw/math/fp_constsl.c b/lib/libc/mingw/math/fp_constsl.c @@ -1,25 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include "fp_consts.h" -#include <math.h> - -const union _ieee_rep __QNANL = { __LONG_DOUBLE_QNAN_REP }; -const union _ieee_rep __SNANL = { __LONG_DOUBLE_SNAN_REP }; -const union _ieee_rep __INFL = { __LONG_DOUBLE_INF_REP }; -const union _ieee_rep __DENORML = { __LONG_DOUBLE_DENORM_REP }; - -#undef nanl -/* FIXME */ -long double nanl (const char *); -long double nanl (const char * tagp __attribute__((unused)) ) -{ -#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ - return nan(""); -#else - return __QNANL.ldouble_val; -#endif -} - diff --git a/lib/libc/musl/src/math/nan.c b/lib/libc/musl/src/math/nan.c @@ -1,6 +0,0 @@ -#include <math.h> - -double nan(const char *s) -{ - return NAN; -} diff --git a/lib/libc/musl/src/math/nanf.c b/lib/libc/musl/src/math/nanf.c @@ -1,6 +0,0 @@ -#include <math.h> - -float nanf(const char *s) -{ - return NAN; -} diff --git a/lib/libc/musl/src/math/nanl.c b/lib/libc/musl/src/math/nanl.c @@ -1,6 +0,0 @@ -#include <math.h> - -long double nanl(const char *s) -{ - return NAN; -} diff --git a/lib/libc/musl/src/stdlib/bsearch.c b/lib/libc/musl/src/stdlib/bsearch.c @@ -1,20 +0,0 @@ -#include <stdlib.h> - -void *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *)) -{ - void *try; - int sign; - while (nel > 0) { - try = (char *)base + width*(nel/2); - sign = cmp(key, try); - if (sign < 0) { - nel /= 2; - } else if (sign > 0) { - base = (char *)try + width; - nel -= nel/2+1; - } else { - return try; - } - } - return NULL; -} diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig @@ -610,9 +610,6 @@ const mingw32_generic_src = [_][]const u8{ "gdtoa" ++ path.sep_str ++ "sum.c", "gdtoa" ++ path.sep_str ++ "ulp.c", "math" ++ path.sep_str ++ "coshl.c", - "math" ++ path.sep_str ++ "fp_consts.c", - "math" ++ path.sep_str ++ "fp_constsf.c", - "math" ++ path.sep_str ++ "fp_constsl.c", "math" ++ path.sep_str ++ "fpclassify.c", "math" ++ path.sep_str ++ "fpclassifyf.c", "math" ++ path.sep_str ++ "fpclassifyl.c", diff --git a/src/libs/musl.zig b/src/libs/musl.zig @@ -1045,9 +1045,6 @@ const src_files = [_][]const u8{ "musl/src/math/modf.c", "musl/src/math/modff.c", "musl/src/math/modfl.c", - "musl/src/math/nan.c", - "musl/src/math/nanf.c", - "musl/src/math/nanl.c", "musl/src/math/nearbyint.c", "musl/src/math/nearbyintf.c", "musl/src/math/nearbyintl.c", @@ -1717,7 +1714,6 @@ const src_files = [_][]const u8{ "musl/src/stdlib/atoi.c", "musl/src/stdlib/atol.c", "musl/src/stdlib/atoll.c", - "musl/src/stdlib/bsearch.c", "musl/src/stdlib/ecvt.c", "musl/src/stdlib/fcvt.c", "musl/src/stdlib/gcvt.c", diff --git a/src/libs/wasi_libc.zig b/src/libs/wasi_libc.zig @@ -818,9 +818,6 @@ const libc_top_half_src_files = [_][]const u8{ "musl/src/math/modf.c", "musl/src/math/modff.c", "musl/src/math/modfl.c", - "musl/src/math/nan.c", - "musl/src/math/nanf.c", - "musl/src/math/nanl.c", "musl/src/math/nearbyintl.c", "musl/src/math/nextafter.c", "musl/src/math/nextafterf.c", @@ -1007,7 +1004,6 @@ const libc_top_half_src_files = [_][]const u8{ "musl/src/stdlib/atoi.c", "musl/src/stdlib/atol.c", "musl/src/stdlib/atoll.c", - "musl/src/stdlib/bsearch.c", "musl/src/stdlib/ecvt.c", "musl/src/stdlib/fcvt.c", "musl/src/stdlib/gcvt.c",