| author | |
| committer | |
| log | 820308b3d44ed7ca2cabd07a11b2099992ed4e6b |
| tree | a966df79d83872d0a077cb2579e9fd1f6db1e7d3 |
| parent | f8997aca8f62eef4968e4abf817ece4eb4e91c38 |
| parent | 153990d407e53d965bbb0c2c9ece333737c90363 |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31536
Reviewed-by: Andrew Kelley <andrew@ziglang.org>15 files changed, 133 insertions(+), 487 deletions(-)
lib/c/math.zig+133-17| ... | ... | @@ -2,6 +2,10 @@ const builtin = @import("builtin"); |
| 2 | 2 | |
| 3 | 3 | const std = @import("std"); |
| 4 | 4 | const math = std.math; |
| 5 | const expect = std.testing.expect; | |
| 6 | const expectEqual = std.testing.expectEqual; | |
| 7 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; | |
| 8 | const expectApproxEqRel = std.testing.expectApproxEqRel; | |
| 5 | 9 | |
| 6 | 10 | const symbol = @import("../c.zig").symbol; |
| 7 | 11 | |
| ... | ... | @@ -34,14 +38,19 @@ comptime { |
| 34 | 38 | symbol(&coshf, "coshf"); |
| 35 | 39 | symbol(&hypotf, "hypotf"); |
| 36 | 40 | symbol(&hypotl, "hypotl"); |
| 41 | symbol(&modff, "modff"); | |
| 42 | symbol(&modfl, "modfl"); | |
| 37 | 43 | symbol(&nan, "nan"); |
| 38 | 44 | symbol(&nanf, "nanf"); |
| 39 | 45 | symbol(&nanl, "nanl"); |
| 46 | symbol(&tanhf, "tanhf"); | |
| 40 | 47 | } |
| 41 | 48 | |
| 42 | 49 | if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) { |
| 43 | 50 | symbol(&acos, "acos"); |
| 44 | 51 | symbol(&acosf, "acosf"); |
| 52 | symbol(&acoshf, "acoshf"); | |
| 53 | symbol(&asin, "asin"); | |
| 45 | 54 | symbol(&atan, "atan"); |
| 46 | 55 | symbol(&atanf, "atanf"); |
| 47 | 56 | symbol(&atanl, "atanl"); |
| ... | ... | @@ -51,9 +60,11 @@ comptime { |
| 51 | 60 | symbol(&exp10, "exp10"); |
| 52 | 61 | symbol(&exp10f, "exp10f"); |
| 53 | 62 | symbol(&hypot, "hypot"); |
| 63 | symbol(&modf, "modf"); | |
| 54 | 64 | symbol(&pow, "pow"); |
| 55 | 65 | symbol(&pow10, "pow10"); |
| 56 | 66 | symbol(&pow10f, "pow10f"); |
| 67 | symbol(&tanh, "tanh"); | |
| 57 | 68 | } |
| 58 | 69 | |
| 59 | 70 | if (builtin.target.isMuslLibC()) { |
| ... | ... | @@ -70,7 +81,15 @@ fn acos(x: f64) callconv(.c) f64 { |
| 70 | 81 | } |
| 71 | 82 | |
| 72 | 83 | fn acosf(x: f32) callconv(.c) f32 { |
| 73 | return std.math.acos(x); | |
| 84 | return math.acos(x); | |
| 85 | } | |
| 86 | ||
| 87 | fn acoshf(x: f32) callconv(.c) f32 { | |
| 88 | return math.acosh(x); | |
| 89 | } | |
| 90 | ||
| 91 | fn asin(x: f64) callconv(.c) f64 { | |
| 92 | return math.asin(x); | |
| 74 | 93 | } |
| 75 | 94 | |
| 76 | 95 | fn atan(x: f64) callconv(.c) f64 { |
| ... | ... | @@ -152,6 +171,95 @@ fn isnanl(x: c_longdouble) callconv(.c) c_int { |
| 152 | 171 | return if (math.isNan(x)) 1 else 0; |
| 153 | 172 | } |
| 154 | 173 | |
| 174 | fn modfGeneric(comptime T: type, x: T, iptr: *T) T { | |
| 175 | if (math.isNegativeInf(x)) { | |
| 176 | iptr.* = -math.inf(T); | |
| 177 | return -0.0; | |
| 178 | } | |
| 179 | ||
| 180 | if (math.isPositiveInf(x)) { | |
| 181 | iptr.* = math.inf(T); | |
| 182 | return 0.0; | |
| 183 | } | |
| 184 | ||
| 185 | if (math.isNan(x)) { | |
| 186 | iptr.* = math.nan(T); | |
| 187 | return math.nan(T); | |
| 188 | } | |
| 189 | ||
| 190 | const r = math.modf(x); | |
| 191 | iptr.* = r.ipart; | |
| 192 | ||
| 193 | // If the result is a negative zero, we must be explicit about | |
| 194 | // returning a negative zero. | |
| 195 | return if (math.isNegativeZero(x) or (x < 0.0 and x == r.ipart)) -0.0 else r.fpart; | |
| 196 | } | |
| 197 | ||
| 198 | fn modf(x: f64, iptr: *f64) callconv(.c) f64 { | |
| 199 | return modfGeneric(f64, x, iptr); | |
| 200 | } | |
| 201 | ||
| 202 | fn modff(x: f32, iptr: *f32) callconv(.c) f32 { | |
| 203 | return modfGeneric(f32, x, iptr); | |
| 204 | } | |
| 205 | ||
| 206 | fn modfl(x: c_longdouble, iptr: *c_longdouble) callconv(.c) c_longdouble { | |
| 207 | return modfGeneric(c_longdouble, x, iptr); | |
| 208 | } | |
| 209 | ||
| 210 | fn testModf(comptime T: type) !void { | |
| 211 | // Choose the appropriate `modf` impl to test based on type | |
| 212 | const f = switch (T) { | |
| 213 | f32 => modff, | |
| 214 | f64 => modf, | |
| 215 | c_longdouble => modfl, | |
| 216 | else => @compileError("modf not implemented for " ++ @typeName(T)), | |
| 217 | }; | |
| 218 | ||
| 219 | var int: T = undefined; | |
| 220 | const iptr = &int; | |
| 221 | const eps_val: comptime_float = @max(1e-6, math.floatEps(T)); | |
| 222 | ||
| 223 | const normal_frac = f(@as(T, 1234.567), iptr); | |
| 224 | // Account for precision error | |
| 225 | const expected = 1234.567 - @as(T, 1234); | |
| 226 | try expectApproxEqAbs(expected, normal_frac, eps_val); | |
| 227 | try expectApproxEqRel(@as(T, 1234.0), iptr.*, eps_val); | |
| 228 | ||
| 229 | // When `x` is a NaN, NaN is returned and `*iptr` is set to NaN | |
| 230 | const nan_frac = f(math.nan(T), iptr); | |
| 231 | try expect(math.isNan(nan_frac)); | |
| 232 | try expect(math.isNan(iptr.*)); | |
| 233 | ||
| 234 | // When `x` is positive infinity, +0 is returned and `*iptr` is set to | |
| 235 | // positive infinity | |
| 236 | const pos_zero_frac = f(math.inf(T), iptr); | |
| 237 | try expect(math.isPositiveZero(pos_zero_frac)); | |
| 238 | try expect(math.isPositiveInf(iptr.*)); | |
| 239 | ||
| 240 | // When `x` is negative infinity, -0 is returned and `*iptr` is set to | |
| 241 | // negative infinity | |
| 242 | const neg_zero_frac = f(-math.inf(T), iptr); | |
| 243 | try expect(math.isNegativeZero(neg_zero_frac)); | |
| 244 | try expect(math.isNegativeInf(iptr.*)); | |
| 245 | ||
| 246 | // Return -0 when `x` is a negative integer | |
| 247 | const nz_frac = f(@as(T, -1000.0), iptr); | |
| 248 | try expect(math.isNegativeZero(nz_frac)); | |
| 249 | try expectEqual(@as(T, -1000.0), iptr.*); | |
| 250 | ||
| 251 | // Return +0 when `x` is a positive integer | |
| 252 | const pz_frac = f(@as(T, 1000.0), iptr); | |
| 253 | try expect(math.isPositiveZero(pz_frac)); | |
| 254 | try expectEqual(@as(T, 1000.0), iptr.*); | |
| 255 | } | |
| 256 | ||
| 257 | test "modf" { | |
| 258 | try testModf(f32); | |
| 259 | try testModf(f64); | |
| 260 | try testModf(c_longdouble); | |
| 261 | } | |
| 262 | ||
| 155 | 263 | fn nan(_: [*:0]const c_char) callconv(.c) f64 { |
| 156 | 264 | return math.nan(f64); |
| 157 | 265 | } |
| ... | ... | @@ -177,7 +285,7 @@ fn pow10f(x: f32) callconv(.c) f32 { |
| 177 | 285 | } |
| 178 | 286 | |
| 179 | 287 | fn rint(x: f64) callconv(.c) f64 { |
| 180 | const toint: f64 = 1.0 / @as(f64, std.math.floatEps(f64)); | |
| 288 | const toint: f64 = 1.0 / @as(f64, math.floatEps(f64)); | |
| 181 | 289 | const a: u64 = @bitCast(x); |
| 182 | 290 | const e = a >> 52 & 0x7ff; |
| 183 | 291 | const s = a >> 63; |
| ... | ... | @@ -199,35 +307,43 @@ fn rint(x: f64) callconv(.c) f64 { |
| 199 | 307 | |
| 200 | 308 | test "rint" { |
| 201 | 309 | // Positive numbers round correctly |
| 202 | try std.testing.expectEqual(@as(f64, 42.0), rint(42.2)); | |
| 203 | try std.testing.expectEqual(@as(f64, 42.0), rint(41.8)); | |
| 310 | try expectEqual(@as(f64, 42.0), rint(42.2)); | |
| 311 | try expectEqual(@as(f64, 42.0), rint(41.8)); | |
| 204 | 312 | |
| 205 | 313 | // Negative numbers round correctly |
| 206 | try std.testing.expectEqual(@as(f64, -6.0), rint(-5.9)); | |
| 207 | try std.testing.expectEqual(@as(f64, -6.0), rint(-6.1)); | |
| 314 | try expectEqual(@as(f64, -6.0), rint(-5.9)); | |
| 315 | try expectEqual(@as(f64, -6.0), rint(-6.1)); | |
| 208 | 316 | |
| 209 | 317 | // No rounding needed test |
| 210 | try std.testing.expectEqual(@as(f64, 5.0), rint(5.0)); | |
| 211 | try std.testing.expectEqual(@as(f64, -10.0), rint(-10.0)); | |
| 212 | try std.testing.expectEqual(@as(f64, 0.0), rint(0.0)); | |
| 318 | try expectEqual(@as(f64, 5.0), rint(5.0)); | |
| 319 | try expectEqual(@as(f64, -10.0), rint(-10.0)); | |
| 320 | try expectEqual(@as(f64, 0.0), rint(0.0)); | |
| 213 | 321 | |
| 214 | 322 | // Very large numbers return unchanged |
| 215 | 323 | const large: f64 = 9007199254740992.0; // 2^53 |
| 216 | try std.testing.expectEqual(large, rint(large)); | |
| 217 | try std.testing.expectEqual(-large, rint(-large)); | |
| 324 | try expectEqual(large, rint(large)); | |
| 325 | try expectEqual(-large, rint(-large)); | |
| 218 | 326 | |
| 219 | 327 | // Small positive numbers round to zero |
| 220 | 328 | const pos_result = rint(0.3); |
| 221 | try std.testing.expectEqual(@as(f64, 0.0), pos_result); | |
| 222 | try std.testing.expect(@as(u64, @bitCast(pos_result)) == 0); | |
| 329 | try expectEqual(@as(f64, 0.0), pos_result); | |
| 330 | try expect(@as(u64, @bitCast(pos_result)) == 0); | |
| 223 | 331 | |
| 224 | 332 | // Small negative numbers round to negative zero |
| 225 | 333 | const neg_result = rint(-0.3); |
| 226 | try std.testing.expectEqual(@as(f64, 0.0), neg_result); | |
| 334 | try expectEqual(@as(f64, 0.0), neg_result); | |
| 227 | 335 | const bits: u64 = @bitCast(neg_result); |
| 228 | try std.testing.expect((bits >> 63) == 1); | |
| 336 | try expect((bits >> 63) == 1); | |
| 229 | 337 | |
| 230 | 338 | // Exact half rounds to nearest even (banker's rounding) |
| 231 | try std.testing.expectEqual(@as(f64, 2.0), rint(2.5)); | |
| 232 | try std.testing.expectEqual(@as(f64, 4.0), rint(3.5)); | |
| 339 | try expectEqual(@as(f64, 2.0), rint(2.5)); | |
| 340 | try expectEqual(@as(f64, 4.0), rint(3.5)); | |
| 341 | } | |
| 342 | ||
| 343 | fn tanh(x: f64) callconv(.c) f64 { | |
| 344 | return math.tanh(x); | |
| 345 | } | |
| 346 | ||
| 347 | fn tanhf(x: f32) callconv(.c) f32 { | |
| 348 | return math.tanh(x); | |
| 233 | 349 | } |
lib/libc/mingw/math/modff.c deleted-42| ... | ... | @@ -1,42 +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 | */ | |
| 6 | #include <fenv.h> | |
| 7 | #include <math.h> | |
| 8 | #include <errno.h> | |
| 9 | ||
| 10 | float | |
| 11 | modff (float value, float* iptr) | |
| 12 | { | |
| 13 | float int_part = 0.0F; | |
| 14 | /* truncate */ | |
| 15 | /* truncate */ | |
| 16 | #if (defined(_AMD64_) && !defined(_ARM64EC_)) || (defined(__x86_64__) && !defined(__arm64ec__)) | |
| 17 | asm volatile ("subq $8, %%rsp\n" | |
| 18 | "fnstcw 4(%%rsp)\n" | |
| 19 | "movzwl 4(%%rsp), %%eax\n" | |
| 20 | "orb $12, %%ah\n" | |
| 21 | "movw %%ax, (%%rsp)\n" | |
| 22 | "fldcw (%%rsp)\n" | |
| 23 | "frndint\n" | |
| 24 | "fldcw 4(%%rsp)\n" | |
| 25 | "addq $8, %%rsp\n" : "=t" (int_part) : "0" (value) : "eax"); /* round */ | |
| 26 | #elif defined(_X86_) || defined(__i386__) | |
| 27 | asm volatile ("push %%eax\n\tsubl $8, %%esp\n" | |
| 28 | "fnstcw 4(%%esp)\n" | |
| 29 | "movzwl 4(%%esp), %%eax\n" | |
| 30 | "orb $12, %%ah\n" | |
| 31 | "movw %%ax, (%%esp)\n" | |
| 32 | "fldcw (%%esp)\n" | |
| 33 | "frndint\n" | |
| 34 | "fldcw 4(%%esp)\n" | |
| 35 | "addl $8, %%esp\n\tpop %%eax\n" : "=t" (int_part) : "0" (value) : "eax"); /* round */ | |
| 36 | #else | |
| 37 | int_part = truncf(value); | |
| 38 | #endif | |
| 39 | if (iptr) | |
| 40 | *iptr = int_part; | |
| 41 | return (isinf (value) ? 0.0F : value - int_part); | |
| 42 | } |
lib/libc/mingw/math/modfl.c deleted-41| ... | ... | @@ -1,41 +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 | */ | |
| 6 | #include <fenv.h> | |
| 7 | #include <math.h> | |
| 8 | #include <errno.h> | |
| 9 | ||
| 10 | long double | |
| 11 | modfl (long double value, long double* iptr) | |
| 12 | { | |
| 13 | long double int_part = 0.0L; | |
| 14 | /* truncate */ | |
| 15 | #if (defined(_AMD64_) && !defined(_ARM64EC_)) || (defined(__x86_64__) && !defined(__arm64ec__)) | |
| 16 | asm volatile ("subq $8, %%rsp\n" | |
| 17 | "fnstcw 4(%%rsp)\n" | |
| 18 | "movzwl 4(%%rsp), %%eax\n" | |
| 19 | "orb $12, %%ah\n" | |
| 20 | "movw %%ax, (%%rsp)\n" | |
| 21 | "fldcw (%%rsp)\n" | |
| 22 | "frndint\n" | |
| 23 | "fldcw 4(%%rsp)\n" | |
| 24 | "addq $8, %%rsp\n" : "=t" (int_part) : "0" (value) : "eax"); /* round */ | |
| 25 | #elif defined(_X86_) || defined(__i386__) | |
| 26 | asm volatile ("push %%eax\n\tsubl $8, %%esp\n" | |
| 27 | "fnstcw 4(%%esp)\n" | |
| 28 | "movzwl 4(%%esp), %%eax\n" | |
| 29 | "orb $12, %%ah\n" | |
| 30 | "movw %%ax, (%%esp)\n" | |
| 31 | "fldcw (%%esp)\n" | |
| 32 | "frndint\n" | |
| 33 | "fldcw 4(%%esp)\n" | |
| 34 | "addl $8, %%esp\n\tpop %%eax\n" : "=t" (int_part) : "0" (value) : "eax"); /* round */ | |
| 35 | #else | |
| 36 | int_part = truncl(value); | |
| 37 | #endif | |
| 38 | if (iptr) | |
| 39 | *iptr = int_part; | |
| 40 | return (isinf (value) ? 0.0L : value - int_part); | |
| 41 | } |
lib/libc/mingw/math/tanhf.c deleted-10| ... | ... | @@ -1,10 +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 | */ | |
| 6 | #include <math.h> | |
| 7 | float tanhf (float x) | |
| 8 | { | |
| 9 | return (float) tanh (x); | |
| 10 | } |
lib/libc/musl/src/math/acoshf.c deleted-26| ... | ... | @@ -1,26 +0,0 @@ |
| 1 | #include "libm.h" | |
| 2 | ||
| 3 | #if FLT_EVAL_METHOD==2 | |
| 4 | #undef sqrtf | |
| 5 | #define sqrtf sqrtl | |
| 6 | #elif FLT_EVAL_METHOD==1 | |
| 7 | #undef sqrtf | |
| 8 | #define sqrtf sqrt | |
| 9 | #endif | |
| 10 | ||
| 11 | /* acosh(x) = log(x + sqrt(x*x-1)) */ | |
| 12 | float acoshf(float x) | |
| 13 | { | |
| 14 | 	union {float f; uint32_t i;} u = {x}; | |
| 15 | 	uint32_t a = u.i & 0x7fffffff; | |
| 16 | ||
| 17 | 	if (a < 0x3f800000+(1<<23)) | |
| 18 | 		/* |x| < 2, invalid if x < 1 */ | |
| 19 | 		/* up to 2ulp error in [1,1.125] */ | |
| 20 | 		return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1))); | |
| 21 | 	if (u.i < 0x3f800000+(12<<23)) | |
| 22 | 		/* 2 <= x < 0x1p12 */ | |
| 23 | 		return logf(2*x - 1/(x+sqrtf(x*x-1))); | |
| 24 | 	/* x >= 0x1p12 or x <= -2 or nan */ | |
| 25 | 	return logf(x) + 0.693147180559945309417232121458176568f; | |
| 26 | } |
lib/libc/musl/src/math/asin.c deleted-107| ... | ... | @@ -1,107 +0,0 @@ |
| 1 | /* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */ | |
| 2 | /* | |
| 3 | * ==================================================== | |
| 4 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | |
| 5 | * | |
| 6 | * Developed at SunSoft, a Sun Microsystems, Inc. business. | |
| 7 | * Permission to use, copy, modify, and distribute this | |
| 8 | * software is freely granted, provided that this notice | |
| 9 | * is preserved. | |
| 10 | * ==================================================== | |
| 11 | */ | |
| 12 | /* asin(x) | |
| 13 | * Method : | |
| 14 | * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... | |
| 15 | * we approximate asin(x) on [0,0.5] by | |
| 16 | * asin(x) = x + x*x^2*R(x^2) | |
| 17 | * where | |
| 18 | * R(x^2) is a rational approximation of (asin(x)-x)/x^3 | |
| 19 | * and its remez error is bounded by | |
| 20 | * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75) | |
| 21 | * | |
| 22 | * For x in [0.5,1] | |
| 23 | * asin(x) = pi/2-2*asin(sqrt((1-x)/2)) | |
| 24 | * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2; | |
| 25 | * then for x>0.98 | |
| 26 | * asin(x) = pi/2 - 2*(s+s*z*R(z)) | |
| 27 | * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) | |
| 28 | * For x<=0.98, let pio4_hi = pio2_hi/2, then | |
| 29 | * f = hi part of s; | |
| 30 | * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) | |
| 31 | * and | |
| 32 | * asin(x) = pi/2 - 2*(s+s*z*R(z)) | |
| 33 | * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) | |
| 34 | * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) | |
| 35 | * | |
| 36 | * Special cases: | |
| 37 | * if x is NaN, return x itself; | |
| 38 | * if |x|>1, return NaN with invalid signal. | |
| 39 | * | |
| 40 | */ | |
| 41 | ||
| 42 | #include "libm.h" | |
| 43 | ||
| 44 | static const double | |
| 45 | pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ | |
| 46 | pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ | |
| 47 | /* coefficients for R(x^2) */ | |
| 48 | pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ | |
| 49 | pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ | |
| 50 | pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ | |
| 51 | pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ | |
| 52 | pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ | |
| 53 | pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ | |
| 54 | qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ | |
| 55 | qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ | |
| 56 | qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ | |
| 57 | qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ | |
| 58 | ||
| 59 | static double R(double z) | |
| 60 | { | |
| 61 | 	double_t p, q; | |
| 62 | 	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); | |
| 63 | 	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4))); | |
| 64 | 	return p/q; | |
| 65 | } | |
| 66 | ||
| 67 | double asin(double x) | |
| 68 | { | |
| 69 | 	double z,r,s; | |
| 70 | 	uint32_t hx,ix; | |
| 71 | ||
| 72 | 	GET_HIGH_WORD(hx, x); | |
| 73 | 	ix = hx & 0x7fffffff; | |
| 74 | 	/* |x| >= 1 or nan */ | |
| 75 | 	if (ix >= 0x3ff00000) { | |
| 76 | 		uint32_t lx; | |
| 77 | 		GET_LOW_WORD(lx, x); | |
| 78 | 		if ((ix-0x3ff00000 | lx) == 0) | |
| 79 | 			/* asin(1) = +-pi/2 with inexact */ | |
| 80 | 			return x*pio2_hi + 0x1p-120f; | |
| 81 | 		return 0/(x-x); | |
| 82 | 	} | |
| 83 | 	/* |x| < 0.5 */ | |
| 84 | 	if (ix < 0x3fe00000) { | |
| 85 | 		/* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */ | |
| 86 | 		if (ix < 0x3e500000 && ix >= 0x00100000) | |
| 87 | 			return x; | |
| 88 | 		return x + x*R(x*x); | |
| 89 | 	} | |
| 90 | 	/* 1 > |x| >= 0.5 */ | |
| 91 | 	z = (1 - fabs(x))*0.5; | |
| 92 | 	s = sqrt(z); | |
| 93 | 	r = R(z); | |
| 94 | 	if (ix >= 0x3fef3333) { /* if |x| > 0.975 */ | |
| 95 | 		x = pio2_hi-(2*(s+s*r)-pio2_lo); | |
| 96 | 	} else { | |
| 97 | 		double f,c; | |
| 98 | 		/* f+c = sqrt(z) */ | |
| 99 | 		f = s; | |
| 100 | 		SET_LOW_WORD(f,0); | |
| 101 | 		c = (z-f*f)/(s+f); | |
| 102 | 		x = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f)); | |
| 103 | 	} | |
| 104 | 	if (hx >> 31) | |
| 105 | 		return -x; | |
| 106 | 	return x; | |
| 107 | } |
lib/libc/musl/src/math/i386/asin.s deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | .global asin | |
| 2 | .type asin,@function | |
| 3 | asin: | |
| 4 | 	fldl 4(%esp) | |
| 5 | 	mov 8(%esp),%eax | |
| 6 | 	add %eax,%eax | |
| 7 | 	cmp $0x00200000,%eax | |
| 8 | 	jb 1f | |
| 9 | 	fld %st(0) | |
| 10 | 	fld1 | |
| 11 | 	fsub %st(0),%st(1) | |
| 12 | 	fadd %st(2) | |
| 13 | 	fmulp | |
| 14 | 	fsqrt | |
| 15 | 	fpatan | |
| 16 | 	fstpl 4(%esp) | |
| 17 | 	fldl 4(%esp) | |
| 18 | 	ret | |
| 19 | 		# subnormal x, return x with underflow | |
| 20 | 1:	fsts 4(%esp) | |
| 21 | 	ret |
lib/libc/musl/src/math/modf.c deleted-34| ... | ... | @@ -1,34 +0,0 @@ |
| 1 | #include "libm.h" | |
| 2 | ||
| 3 | double modf(double x, double *iptr) | |
| 4 | { | |
| 5 | 	union {double f; uint64_t i;} u = {x}; | |
| 6 | 	uint64_t mask; | |
| 7 | 	int e = (int)(u.i>>52 & 0x7ff) - 0x3ff; | |
| 8 | ||
| 9 | 	/* no fractional part */ | |
| 10 | 	if (e >= 52) { | |
| 11 | 		*iptr = x; | |
| 12 | 		if (e == 0x400 && u.i<<12 != 0) /* nan */ | |
| 13 | 			return x; | |
| 14 | 		u.i &= 1ULL<<63; | |
| 15 | 		return u.f; | |
| 16 | 	} | |
| 17 | ||
| 18 | 	/* no integral part*/ | |
| 19 | 	if (e < 0) { | |
| 20 | 		u.i &= 1ULL<<63; | |
| 21 | 		*iptr = u.f; | |
| 22 | 		return x; | |
| 23 | 	} | |
| 24 | ||
| 25 | 	mask = -1ULL>>12>>e; | |
| 26 | 	if ((u.i & mask) == 0) { | |
| 27 | 		*iptr = x; | |
| 28 | 		u.i &= 1ULL<<63; | |
| 29 | 		return u.f; | |
| 30 | 	} | |
| 31 | 	u.i &= ~mask; | |
| 32 | 	*iptr = u.f; | |
| 33 | 	return x - u.f; | |
| 34 | } |
lib/libc/musl/src/math/modff.c deleted-34| ... | ... | @@ -1,34 +0,0 @@ |
| 1 | #include "libm.h" | |
| 2 | ||
| 3 | float modff(float x, float *iptr) | |
| 4 | { | |
| 5 | 	union {float f; uint32_t i;} u = {x}; | |
| 6 | 	uint32_t mask; | |
| 7 | 	int e = (int)(u.i>>23 & 0xff) - 0x7f; | |
| 8 | ||
| 9 | 	/* no fractional part */ | |
| 10 | 	if (e >= 23) { | |
| 11 | 		*iptr = x; | |
| 12 | 		if (e == 0x80 && u.i<<9 != 0) { /* nan */ | |
| 13 | 			return x; | |
| 14 | 		} | |
| 15 | 		u.i &= 0x80000000; | |
| 16 | 		return u.f; | |
| 17 | 	} | |
| 18 | 	/* no integral part */ | |
| 19 | 	if (e < 0) { | |
| 20 | 		u.i &= 0x80000000; | |
| 21 | 		*iptr = u.f; | |
| 22 | 		return x; | |
| 23 | 	} | |
| 24 | ||
| 25 | 	mask = 0x007fffff>>e; | |
| 26 | 	if ((u.i & mask) == 0) { | |
| 27 | 		*iptr = x; | |
| 28 | 		u.i &= 0x80000000; | |
| 29 | 		return u.f; | |
| 30 | 	} | |
| 31 | 	u.i &= ~mask; | |
| 32 | 	*iptr = u.f; | |
| 33 | 	return x - u.f; | |
| 34 | } |
lib/libc/musl/src/math/modfl.c deleted-53| ... | ... | @@ -1,53 +0,0 @@ |
| 1 | #include "libm.h" | |
| 2 | ||
| 3 | #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 | |
| 4 | long double modfl(long double x, long double *iptr) | |
| 5 | { | |
| 6 | 	double d; | |
| 7 | 	long double r; | |
| 8 | ||
| 9 | 	r = modf(x, &d); | |
| 10 | 	*iptr = d; | |
| 11 | 	return r; | |
| 12 | } | |
| 13 | #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 | |
| 14 | ||
| 15 | static const long double toint = 1/LDBL_EPSILON; | |
| 16 | ||
| 17 | long double modfl(long double x, long double *iptr) | |
| 18 | { | |
| 19 | 	union ldshape u = {x}; | |
| 20 | 	int e = (u.i.se & 0x7fff) - 0x3fff; | |
| 21 | 	int s = u.i.se >> 15; | |
| 22 | 	long double absx; | |
| 23 | 	long double y; | |
| 24 | ||
| 25 | 	/* no fractional part */ | |
| 26 | 	if (e >= LDBL_MANT_DIG-1) { | |
| 27 | 		*iptr = x; | |
| 28 | 		if (isnan(x)) | |
| 29 | 			return x; | |
| 30 | 		return s ? -0.0 : 0.0; | |
| 31 | 	} | |
| 32 | ||
| 33 | 	/* no integral part*/ | |
| 34 | 	if (e < 0) { | |
| 35 | 		*iptr = s ? -0.0 : 0.0; | |
| 36 | 		return x; | |
| 37 | 	} | |
| 38 | ||
| 39 | 	/* raises spurious inexact */ | |
| 40 | 	absx = s ? -x : x; | |
| 41 | 	y = absx + toint - toint - absx; | |
| 42 | 	if (y == 0) { | |
| 43 | 		*iptr = x; | |
| 44 | 		return s ? -0.0 : 0.0; | |
| 45 | 	} | |
| 46 | 	if (y > 0) | |
| 47 | 		y -= 1; | |
| 48 | 	if (s) | |
| 49 | 		y = -y; | |
| 50 | 	*iptr = x + y; | |
| 51 | 	return -y; | |
| 52 | } | |
| 53 | #endif |
lib/libc/musl/src/math/tanh.c deleted-45| ... | ... | @@ -1,45 +0,0 @@ |
| 1 | #include "libm.h" | |
| 2 | ||
| 3 | /* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x)) | |
| 4 | * = (exp(2*x) - 1)/(exp(2*x) - 1 + 2) | |
| 5 | * = (1 - exp(-2*x))/(exp(-2*x) - 1 + 2) | |
| 6 | */ | |
| 7 | double tanh(double x) | |
| 8 | { | |
| 9 | 	union {double f; uint64_t i;} u = {.f = x}; | |
| 10 | 	uint32_t w; | |
| 11 | 	int sign; | |
| 12 | 	double_t t; | |
| 13 | ||
| 14 | 	/* x = |x| */ | |
| 15 | 	sign = u.i >> 63; | |
| 16 | 	u.i &= (uint64_t)-1/2; | |
| 17 | 	x = u.f; | |
| 18 | 	w = u.i >> 32; | |
| 19 | ||
| 20 | 	if (w > 0x3fe193ea) { | |
| 21 | 		/* |x| > log(3)/2 ~= 0.5493 or nan */ | |
| 22 | 		if (w > 0x40340000) { | |
| 23 | 			/* |x| > 20 or nan */ | |
| 24 | 			/* note: this branch avoids raising overflow */ | |
| 25 | 			t = 1 - 0/x; | |
| 26 | 		} else { | |
| 27 | 			t = expm1(2*x); | |
| 28 | 			t = 1 - 2/(t+2); | |
| 29 | 		} | |
| 30 | 	} else if (w > 0x3fd058ae) { | |
| 31 | 		/* |x| > log(5/3)/2 ~= 0.2554 */ | |
| 32 | 		t = expm1(2*x); | |
| 33 | 		t = t/(t+2); | |
| 34 | 	} else if (w >= 0x00100000) { | |
| 35 | 		/* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */ | |
| 36 | 		t = expm1(-2*x); | |
| 37 | 		t = -t/(t+2); | |
| 38 | 	} else { | |
| 39 | 		/* |x| is subnormal */ | |
| 40 | 		/* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */ | |
| 41 | 		FORCE_EVAL((float)x); | |
| 42 | 		t = x; | |
| 43 | 	} | |
| 44 | 	return sign ? -t : t; | |
| 45 | } |
lib/libc/musl/src/math/tanhf.c deleted-39| ... | ... | @@ -1,39 +0,0 @@ |
| 1 | #include "libm.h" | |
| 2 | ||
| 3 | float tanhf(float x) | |
| 4 | { | |
| 5 | 	union {float f; uint32_t i;} u = {.f = x}; | |
| 6 | 	uint32_t w; | |
| 7 | 	int sign; | |
| 8 | 	float t; | |
| 9 | ||
| 10 | 	/* x = |x| */ | |
| 11 | 	sign = u.i >> 31; | |
| 12 | 	u.i &= 0x7fffffff; | |
| 13 | 	x = u.f; | |
| 14 | 	w = u.i; | |
| 15 | ||
| 16 | 	if (w > 0x3f0c9f54) { | |
| 17 | 		/* |x| > log(3)/2 ~= 0.5493 or nan */ | |
| 18 | 		if (w > 0x41200000) { | |
| 19 | 			/* |x| > 10 */ | |
| 20 | 			t = 1 + 0/x; | |
| 21 | 		} else { | |
| 22 | 			t = expm1f(2*x); | |
| 23 | 			t = 1 - 2/(t+2); | |
| 24 | 		} | |
| 25 | 	} else if (w > 0x3e82c578) { | |
| 26 | 		/* |x| > log(5/3)/2 ~= 0.2554 */ | |
| 27 | 		t = expm1f(2*x); | |
| 28 | 		t = t/(t+2); | |
| 29 | 	} else if (w >= 0x00800000) { | |
| 30 | 		/* |x| >= 0x1p-126 */ | |
| 31 | 		t = expm1f(-2*x); | |
| 32 | 		t = -t/(t+2); | |
| 33 | 	} else { | |
| 34 | 		/* |x| is subnormal */ | |
| 35 | 		FORCE_EVAL(x*x); | |
| 36 | 		t = x; | |
| 37 | 	} | |
| 38 | 	return sign ? -t : t; | |
| 39 | } |
src/libs/mingw.zig-3| ... | ... | @@ -619,7 +619,6 @@ const mingw32_generic_src = [_][]const u8{ |
| 619 | 619 | "math" ++ path.sep_str ++ "lgamma.c", |
| 620 | 620 | "math" ++ path.sep_str ++ "lgammaf.c", |
| 621 | 621 | "math" ++ path.sep_str ++ "lgammal.c", |
| 622 | "math" ++ path.sep_str ++ "modfl.c", | |
| 623 | 622 | "math" ++ path.sep_str ++ "powi.c", |
| 624 | 623 | "math" ++ path.sep_str ++ "powif.c", |
| 625 | 624 | "math" ++ path.sep_str ++ "powil.c", |
| ... | ... | @@ -977,10 +976,8 @@ const mingw32_x86_src = [_][]const u8{ |
| 977 | 976 | |
| 978 | 977 | const mingw32_x86_32_src = [_][]const u8{ |
| 979 | 978 | // ucrtbase |
| 980 | "math" ++ path.sep_str ++ "modff.c", | |
| 981 | 979 | "math" ++ path.sep_str ++ "powf.c", |
| 982 | 980 | "math" ++ path.sep_str ++ "sinhf.c", |
| 983 | "math" ++ path.sep_str ++ "tanhf.c", | |
| 984 | 981 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "acosf.c", |
| 985 | 982 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "asinf.c", |
| 986 | 983 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atan2f.c", |
src/libs/musl.zig-8| ... | ... | @@ -796,12 +796,10 @@ const src_files = [_][]const u8{ |
| 796 | 796 | "musl/src/math/aarch64/nearbyintf.c", |
| 797 | 797 | "musl/src/math/aarch64/rintf.c", |
| 798 | 798 | "musl/src/math/acosh.c", |
| 799 | "musl/src/math/acoshf.c", | |
| 800 | 799 | "musl/src/math/acoshl.c", |
| 801 | 800 | "musl/src/math/acosl.c", |
| 802 | 801 | "musl/src/math/arm/fma.c", |
| 803 | 802 | "musl/src/math/arm/fmaf.c", |
| 804 | "musl/src/math/asin.c", | |
| 805 | 803 | "musl/src/math/asinf.c", |
| 806 | 804 | "musl/src/math/asinh.c", |
| 807 | 805 | "musl/src/math/asinhf.c", |
| ... | ... | @@ -849,7 +847,6 @@ const src_files = [_][]const u8{ |
| 849 | 847 | "musl/src/math/i386/acosl.s", |
| 850 | 848 | "musl/src/math/i386/asinf.s", |
| 851 | 849 | "musl/src/math/i386/asinl.s", |
| 852 | "musl/src/math/i386/asin.s", | |
| 853 | 850 | "musl/src/math/i386/atan2f.s", |
| 854 | 851 | "musl/src/math/i386/atan2l.s", |
| 855 | 852 | "musl/src/math/i386/atan2.s", |
| ... | ... | @@ -937,9 +934,6 @@ const src_files = [_][]const u8{ |
| 937 | 934 | "musl/src/math/__math_uflowf.c", |
| 938 | 935 | "musl/src/math/__math_xflow.c", |
| 939 | 936 | "musl/src/math/__math_xflowf.c", |
| 940 | "musl/src/math/modf.c", | |
| 941 | "musl/src/math/modff.c", | |
| 942 | "musl/src/math/modfl.c", | |
| 943 | 937 | "musl/src/math/nearbyint.c", |
| 944 | 938 | "musl/src/math/nearbyintf.c", |
| 945 | 939 | "musl/src/math/nearbyintl.c", |
| ... | ... | @@ -1009,8 +1003,6 @@ const src_files = [_][]const u8{ |
| 1009 | 1003 | "musl/src/math/sinl.c", |
| 1010 | 1004 | "musl/src/math/__tan.c", |
| 1011 | 1005 | "musl/src/math/__tandf.c", |
| 1012 | "musl/src/math/tanh.c", | |
| 1013 | "musl/src/math/tanhf.c", | |
| 1014 | 1006 | "musl/src/math/tanhl.c", |
| 1015 | 1007 | "musl/src/math/__tanl.c", |
| 1016 | 1008 | "musl/src/math/tanl.c", |
src/libs/wasi_libc.zig-7| ... | ... | @@ -665,10 +665,8 @@ const libc_top_half_src_files = [_][]const u8{ |
| 665 | 665 | "musl/src/locale/wcscoll.c", |
| 666 | 666 | "musl/src/locale/wcsxfrm.c", |
| 667 | 667 | "musl/src/math/acosh.c", |
| 668 | "musl/src/math/acoshf.c", | |
| 669 | 668 | "musl/src/math/acoshl.c", |
| 670 | 669 | "musl/src/math/acosl.c", |
| 671 | "musl/src/math/asin.c", | |
| 672 | 670 | "musl/src/math/asinf.c", |
| 673 | 671 | "musl/src/math/asinh.c", |
| 674 | 672 | "musl/src/math/asinhf.c", |
| ... | ... | @@ -757,9 +755,6 @@ const libc_top_half_src_files = [_][]const u8{ |
| 757 | 755 | "musl/src/math/__math_uflowf.c", |
| 758 | 756 | "musl/src/math/__math_xflow.c", |
| 759 | 757 | "musl/src/math/__math_xflowf.c", |
| 760 | "musl/src/math/modf.c", | |
| 761 | "musl/src/math/modff.c", | |
| 762 | "musl/src/math/modfl.c", | |
| 763 | 758 | "musl/src/math/nearbyintl.c", |
| 764 | 759 | "musl/src/math/nextafter.c", |
| 765 | 760 | "musl/src/math/nextafterf.c", |
| ... | ... | @@ -798,8 +793,6 @@ const libc_top_half_src_files = [_][]const u8{ |
| 798 | 793 | "musl/src/math/sinl.c", |
| 799 | 794 | "musl/src/math/__tan.c", |
| 800 | 795 | "musl/src/math/__tandf.c", |
| 801 | "musl/src/math/tanh.c", | |
| 802 | "musl/src/math/tanhf.c", | |
| 803 | 796 | "musl/src/math/tanhl.c", |
| 804 | 797 | "musl/src/math/__tanl.c", |
| 805 | 798 | "musl/src/math/tanl.c", |