mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
libzigc: hypot (#31104)
First time contribution. Implements hypot for libzigc #30978. Commands i run: ``` $ stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib $ stage4/bin/zig build test-libc -Dlibc-test-path=../../libc-test -Dtest-filter=hypot --summary line -fqemu -fwasmtime Build Summary: 725/737 steps succeeded (12 skipped) ``` I also changed std.math.hypot becuase some libc-tests raised fp exceptions. Example: ``` ../../libc-test/src/math/special/hypot.h:8: bad fp exception: RN hypot(0x1p-1074,0x0p+0)=0x1p-1074, want 0 got INEXACT|UNDERFLOW ../../libc-test/src/math/special/hypot.h:9: bad fp exception: RN hypot(0x1p-1074,-0x0p+0)=0x1p-1074, want 0 got INEXACT|UNDERFLOW ``` I also run this command as a quick sanity check: ``` $ stage4/bin/zig build test-std -Dtest-filter=hypot -Dtest-target-filter=x86_64-linux-musl --summary line Build Summary: 5/5 steps succeeded; 136/136 tests passed ``` Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31104 Reviewed-by: Andrew Kelley <andrew@ziglang.org> Co-authored-by: Pivok <pivoc@protonmail.com> Co-committed-by: Pivok <pivoc@protonmail.com>
This commit is contained in:
@@ -41,6 +41,7 @@ comptime {
|
||||
@export(&atanl, .{ .name = "atanl", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&cbrt, .{ .name = "cbrt", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&cbrtf, .{ .name = "cbrtf", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&hypot, .{ .name = "hypot", .linkage = common.linkage, .visibility = common.visibility });
|
||||
@export(&pow, .{ .name = "pow", .linkage = common.linkage, .visibility = common.visibility });
|
||||
}
|
||||
|
||||
@@ -118,6 +119,10 @@ fn cbrtf(x: f32) callconv(.c) f32 {
|
||||
return math.cbrt(x);
|
||||
}
|
||||
|
||||
fn hypot(x: f64, y: f64) callconv(.c) f64 {
|
||||
return math.hypot(x, y);
|
||||
}
|
||||
|
||||
fn pow(x: f64, y: f64) callconv(.c) f64 {
|
||||
return math.pow(f64, x, y);
|
||||
}
|
||||
|
||||
Vendored
-67
@@ -1,67 +0,0 @@
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
|
||||
#if FLT_EVAL_METHOD > 1U && LDBL_MANT_DIG == 64
|
||||
#define SPLIT (0x1p32 + 1)
|
||||
#else
|
||||
#define SPLIT (0x1p27 + 1)
|
||||
#endif
|
||||
|
||||
static void sq(double_t *hi, double_t *lo, double x)
|
||||
{
|
||||
double_t xh, xl, xc;
|
||||
|
||||
xc = (double_t)x*SPLIT;
|
||||
xh = x - xc + xc;
|
||||
xl = x - xh;
|
||||
*hi = (double_t)x*x;
|
||||
*lo = xh*xh - *hi + 2*xh*xl + xl*xl;
|
||||
}
|
||||
|
||||
double hypot(double x, double y)
|
||||
{
|
||||
union {double f; uint64_t i;} ux = {x}, uy = {y}, ut;
|
||||
int ex, ey;
|
||||
double_t hx, lx, hy, ly, z;
|
||||
|
||||
/* arrange |x| >= |y| */
|
||||
ux.i &= -1ULL>>1;
|
||||
uy.i &= -1ULL>>1;
|
||||
if (ux.i < uy.i) {
|
||||
ut = ux;
|
||||
ux = uy;
|
||||
uy = ut;
|
||||
}
|
||||
|
||||
/* special cases */
|
||||
ex = ux.i>>52;
|
||||
ey = uy.i>>52;
|
||||
x = ux.f;
|
||||
y = uy.f;
|
||||
/* note: hypot(inf,nan) == inf */
|
||||
if (ey == 0x7ff)
|
||||
return y;
|
||||
if (ex == 0x7ff || uy.i == 0)
|
||||
return x;
|
||||
/* note: hypot(x,y) ~= x + y*y/x/2 with inexact for small y/x */
|
||||
/* 64 difference is enough for ld80 double_t */
|
||||
if (ex - ey > 64)
|
||||
return x + y;
|
||||
|
||||
/* precise sqrt argument in nearest rounding mode without overflow */
|
||||
/* xh*xh must not overflow and xl*xl must not underflow in sq */
|
||||
z = 1;
|
||||
if (ex > 0x3ff+510) {
|
||||
z = 0x1p700;
|
||||
x *= 0x1p-700;
|
||||
y *= 0x1p-700;
|
||||
} else if (ey < 0x3ff-450) {
|
||||
z = 0x1p-700;
|
||||
x *= 0x1p700;
|
||||
y *= 0x1p700;
|
||||
}
|
||||
sq(&hx, &lx, x);
|
||||
sq(&hy, &ly, y);
|
||||
return z*sqrt(ly+lx+hy+hx);
|
||||
}
|
||||
Vendored
-45
@@ -1,45 +0,0 @@
|
||||
.global hypot
|
||||
.type hypot,@function
|
||||
hypot:
|
||||
mov 8(%esp),%eax
|
||||
mov 16(%esp),%ecx
|
||||
add %eax,%eax
|
||||
add %ecx,%ecx
|
||||
and %eax,%ecx
|
||||
cmp $0xffe00000,%ecx
|
||||
jae 2f
|
||||
or 4(%esp),%eax
|
||||
jnz 1f
|
||||
fldl 12(%esp)
|
||||
fabs
|
||||
ret
|
||||
1: mov 16(%esp),%eax
|
||||
add %eax,%eax
|
||||
or 12(%esp),%eax
|
||||
jnz 1f
|
||||
fldl 4(%esp)
|
||||
fabs
|
||||
ret
|
||||
1: fldl 4(%esp)
|
||||
fld %st(0)
|
||||
fmulp
|
||||
fldl 12(%esp)
|
||||
fld %st(0)
|
||||
fmulp
|
||||
faddp
|
||||
fsqrt
|
||||
ret
|
||||
2: sub $0xffe00000,%eax
|
||||
or 4(%esp),%eax
|
||||
jnz 1f
|
||||
fldl 4(%esp)
|
||||
fabs
|
||||
ret
|
||||
1: mov 16(%esp),%eax
|
||||
add %eax,%eax
|
||||
sub $0xffe00000,%eax
|
||||
or 12(%esp),%eax
|
||||
fldl 12(%esp)
|
||||
jnz 1f
|
||||
fabs
|
||||
1: ret
|
||||
@@ -6,10 +6,10 @@ const isNan = math.isNan;
|
||||
const isInf = math.isInf;
|
||||
const inf = math.inf;
|
||||
const nan = math.nan;
|
||||
const floatEpsAt = math.floatEpsAt;
|
||||
const floatEps = math.floatEps;
|
||||
const floatMin = math.floatMin;
|
||||
const floatMax = math.floatMax;
|
||||
const floatTrueMin = math.floatTrueMin;
|
||||
|
||||
/// Returns sqrt(x * x + y * y), avoiding unnecessary overflow and underflow.
|
||||
///
|
||||
@@ -30,8 +30,7 @@ pub fn hypot(x: anytype, y: anytype) @TypeOf(x, y) {
|
||||
}
|
||||
const lower = @sqrt(floatMin(T));
|
||||
const upper = @sqrt(floatMax(T) / 2);
|
||||
const incre = @sqrt(floatEps(T) / 2);
|
||||
const scale = floatEpsAt(T, incre);
|
||||
const scale = floatTrueMin(T) * upper;
|
||||
const hypfn = if (emulateFma(T)) hypotUnfused else hypotFused;
|
||||
var major: T = x;
|
||||
var minor: T = y;
|
||||
@@ -46,7 +45,8 @@ pub fn hypot(x: anytype, y: anytype) @TypeOf(x, y) {
|
||||
major = minor;
|
||||
minor = tempo;
|
||||
}
|
||||
if (major * incre >= minor) return major;
|
||||
if (minor == 0.0) return major;
|
||||
if (major - minor == major) return major;
|
||||
if (major > upper) return hypfn(T, major * scale, minor * scale) / scale;
|
||||
if (minor < lower) return hypfn(T, major / scale, minor / scale) * scale;
|
||||
return hypfn(T, major, minor);
|
||||
|
||||
@@ -874,7 +874,6 @@ const src_files = [_][]const u8{
|
||||
"musl/src/math/frexp.c",
|
||||
"musl/src/math/frexpf.c",
|
||||
"musl/src/math/frexpl.c",
|
||||
"musl/src/math/hypot.c",
|
||||
"musl/src/math/hypotf.c",
|
||||
"musl/src/math/hypotl.c",
|
||||
"musl/src/math/i386/acosf.s",
|
||||
@@ -890,7 +889,6 @@ const src_files = [_][]const u8{
|
||||
"musl/src/math/i386/expl.s",
|
||||
"musl/src/math/i386/expm1l.s",
|
||||
"musl/src/math/i386/hypotf.s",
|
||||
"musl/src/math/i386/hypot.s",
|
||||
"musl/src/math/i386/__invtrigl.s",
|
||||
"musl/src/math/i386/ldexpf.s",
|
||||
"musl/src/math/i386/ldexpl.s",
|
||||
|
||||
@@ -730,7 +730,6 @@ const libc_top_half_src_files = [_][]const u8{
|
||||
"musl/src/math/frexp.c",
|
||||
"musl/src/math/frexpf.c",
|
||||
"musl/src/math/frexpl.c",
|
||||
"musl/src/math/hypot.c",
|
||||
"musl/src/math/hypotf.c",
|
||||
"musl/src/math/hypotl.c",
|
||||
"musl/src/math/ilogb.c",
|
||||
|
||||
Reference in New Issue
Block a user