mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
feat(libzigc): add nan, nanf, nanl and bsearch
* also remove musl implementation
This commit is contained in:
committed by
Andrew Kelley
parent
ecea8cc16d
commit
7f6eab2704
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
-20
@@ -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;
|
||||
}
|
||||
|
||||
Vendored
-50
@@ -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 */
|
||||
|
||||
Vendored
-22
@@ -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;
|
||||
}
|
||||
|
||||
Vendored
-25
@@ -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
|
||||
}
|
||||
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
#include <math.h>
|
||||
|
||||
double nan(const char *s)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
#include <math.h>
|
||||
|
||||
float nanf(const char *s)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
#include <math.h>
|
||||
|
||||
long double nanl(const char *s)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
Vendored
-20
@@ -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;
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user