| author | |
| committer | |
| log | 9f0a38ac815d4d38a3afec6628827f79fdf43b98 |
| tree | bdc327508057d946facf9e6b672ffb50884e8157 |
| parent | cbc62662046c321bbdbb9315a3658ee50234033f |
9 files changed, 25 insertions(+), 277 deletions(-)
lib/c/math.zig+10| ... | @@ -72,6 +72,8 @@ comptime { | ... | @@ -72,6 +72,8 @@ comptime { |
| 72 | symbol(&finitef, "finitef"); | 72 | symbol(&finitef, "finitef"); |
| 73 | symbol(&frexp, "frexp"); | 73 | symbol(&frexp, "frexp"); |
| 74 | symbol(&hypot, "hypot"); | 74 | symbol(&hypot, "hypot"); |
| 75 | symbol(&log1p, "log1p"); | ||
| 76 | symbol(&log1pf, "log1pf"); | ||
| 75 | symbol(&lrint, "lrint"); | 77 | symbol(&lrint, "lrint"); |
| 76 | symbol(&lrintf, "lrintf"); | 78 | symbol(&lrintf, "lrintf"); |
| 77 | symbol(&modf, "modf"); | 79 | symbol(&modf, "modf"); |
| ... | @@ -256,6 +258,14 @@ fn isnanl(x: c_longdouble) callconv(.c) c_int { | ... | @@ -256,6 +258,14 @@ fn isnanl(x: c_longdouble) callconv(.c) c_int { |
| 256 | return @intFromBool(math.isNan(x)); | 258 | return @intFromBool(math.isNan(x)); |
| 257 | } | 259 | } |
| 258 | 260 | ||
| 261 | fn log1p(x: f64) callconv(.c) f64 { | ||
| 262 | return math.log1p(x); | ||
| 263 | } | ||
| 264 | |||
| 265 | fn log1pf(x: f32) callconv(.c) f32 { | ||
| 266 | return math.log1p(x); | ||
| 267 | } | ||
| 268 | |||
| 259 | fn lrint(x: f64) callconv(.c) c_long { | 269 | fn lrint(x: f64) callconv(.c) c_long { |
| 260 | return @trunc(rint(x)); | 270 | return @trunc(rint(x)); |
| 261 | } | 271 | } |
lib/libc/musl/src/math/i386/log1p.s deleted-25| ... | @@ -1,25 +0,0 @@ | ||
| 1 | .global log1p | ||
| 2 | .type log1p,@function | ||
| 3 | log1p: | ||
| 4 | 	mov 8(%esp),%eax | ||
| 5 | 	fldln2 | ||
| 6 | 	and $0x7fffffff,%eax | ||
| 7 | 	fldl 4(%esp) | ||
| 8 | 	cmp $0x3fd28f00,%eax | ||
| 9 | 	ja 1f | ||
| 10 | 	cmp $0x00100000,%eax | ||
| 11 | 	jb 2f | ||
| 12 | 	fyl2xp1 | ||
| 13 | 	fstpl 4(%esp) | ||
| 14 | 	fldl 4(%esp) | ||
| 15 | 	ret | ||
| 16 | 1:	fld1 | ||
| 17 | 	faddp | ||
| 18 | 	fyl2x | ||
| 19 | 	fstpl 4(%esp) | ||
| 20 | 	fldl 4(%esp) | ||
| 21 | 	ret | ||
| 22 | 		# subnormal x, return x with underflow | ||
| 23 | 2:	fsts 4(%esp) | ||
| 24 | 	fstp %st(1) | ||
| 25 | 	ret | ||
lib/libc/musl/src/math/i386/log1pf.s deleted-26| ... | @@ -1,26 +0,0 @@ | ||
| 1 | .global log1pf | ||
| 2 | .type log1pf,@function | ||
| 3 | log1pf: | ||
| 4 | 	mov 4(%esp),%eax | ||
| 5 | 	fldln2 | ||
| 6 | 	and $0x7fffffff,%eax | ||
| 7 | 	flds 4(%esp) | ||
| 8 | 	cmp $0x3e940000,%eax | ||
| 9 | 	ja 1f | ||
| 10 | 	cmp $0x00800000,%eax | ||
| 11 | 	jb 2f | ||
| 12 | 	fyl2xp1 | ||
| 13 | 	fstps 4(%esp) | ||
| 14 | 	flds 4(%esp) | ||
| 15 | 	ret | ||
| 16 | 1:	fld1 | ||
| 17 | 	faddp | ||
| 18 | 	fyl2x | ||
| 19 | 	fstps 4(%esp) | ||
| 20 | 	flds 4(%esp) | ||
| 21 | 	ret | ||
| 22 | 		# subnormal x, return x with underflow | ||
| 23 | 2:	fxch | ||
| 24 | 	fmul %st(1) | ||
| 25 | 	fstps 4(%esp) | ||
| 26 | 	ret | ||
lib/libc/musl/src/math/log1p.c deleted-122| ... | @@ -1,122 +0,0 @@ | ||
| 1 | /* origin: FreeBSD /usr/src/lib/msun/src/s_log1p.c */ | ||
| 2 | /* | ||
| 3 | * ==================================================== | ||
| 4 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | ||
| 5 | * | ||
| 6 | * Developed at SunPro, 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 | /* double log1p(double x) | ||
| 13 | * Return the natural logarithm of 1+x. | ||
| 14 | * | ||
| 15 | * Method : | ||
| 16 | * 1. Argument Reduction: find k and f such that | ||
| 17 | * 1+x = 2^k * (1+f), | ||
| 18 | * where sqrt(2)/2 < 1+f < sqrt(2) . | ||
| 19 | * | ||
| 20 | * Note. If k=0, then f=x is exact. However, if k!=0, then f | ||
| 21 | * may not be representable exactly. In that case, a correction | ||
| 22 | * term is need. Let u=1+x rounded. Let c = (1+x)-u, then | ||
| 23 | * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), | ||
| 24 | * and add back the correction term c/u. | ||
| 25 | * (Note: when x > 2**53, one can simply return log(x)) | ||
| 26 | * | ||
| 27 | * 2. Approximation of log(1+f): See log.c | ||
| 28 | * | ||
| 29 | * 3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c | ||
| 30 | * | ||
| 31 | * Special cases: | ||
| 32 | * log1p(x) is NaN with signal if x < -1 (including -INF) ; | ||
| 33 | * log1p(+INF) is +INF; log1p(-1) is -INF with signal; | ||
| 34 | * log1p(NaN) is that NaN with no signal. | ||
| 35 | * | ||
| 36 | * Accuracy: | ||
| 37 | * according to an error analysis, the error is always less than | ||
| 38 | * 1 ulp (unit in the last place). | ||
| 39 | * | ||
| 40 | * Constants: | ||
| 41 | * The hexadecimal values are the intended ones for the following | ||
| 42 | * constants. The decimal values may be used, provided that the | ||
| 43 | * compiler will convert from decimal to binary accurately enough | ||
| 44 | * to produce the hexadecimal values shown. | ||
| 45 | * | ||
| 46 | * Note: Assuming log() return accurate answer, the following | ||
| 47 | * algorithm can be used to compute log1p(x) to within a few ULP: | ||
| 48 | * | ||
| 49 | * u = 1+x; | ||
| 50 | * if(u==1.0) return x ; else | ||
| 51 | * return log(u)*(x/(u-1.0)); | ||
| 52 | * | ||
| 53 | * See HP-15C Advanced Functions Handbook, p.193. | ||
| 54 | */ | ||
| 55 | |||
| 56 | #include "libm.h" | ||
| 57 | |||
| 58 | static const double | ||
| 59 | ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ | ||
| 60 | ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ | ||
| 61 | Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ | ||
| 62 | Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ | ||
| 63 | Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ | ||
| 64 | Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ | ||
| 65 | Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ | ||
| 66 | Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ | ||
| 67 | Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ | ||
| 68 | |||
| 69 | double log1p(double x) | ||
| 70 | { | ||
| 71 | 	union {double f; uint64_t i;} u = {x}; | ||
| 72 | 	double_t hfsq,f,c,s,z,R,w,t1,t2,dk; | ||
| 73 | 	uint32_t hx,hu; | ||
| 74 | 	int k; | ||
| 75 | |||
| 76 | 	hx = u.i>>32; | ||
| 77 | 	k = 1; | ||
| 78 | 	if (hx < 0x3fda827a || hx>>31) { /* 1+x < sqrt(2)+ */ | ||
| 79 | 		if (hx >= 0xbff00000) { /* x <= -1.0 */ | ||
| 80 | 			if (x == -1) | ||
| 81 | 				return x/0.0; /* log1p(-1) = -inf */ | ||
| 82 | 			return (x-x)/0.0; /* log1p(x<-1) = NaN */ | ||
| 83 | 		} | ||
| 84 | 		if (hx<<1 < 0x3ca00000<<1) { /* |x| < 2**-53 */ | ||
| 85 | 			/* underflow if subnormal */ | ||
| 86 | 			if ((hx&0x7ff00000) == 0) | ||
| 87 | 				FORCE_EVAL((float)x); | ||
| 88 | 			return x; | ||
| 89 | 		} | ||
| 90 | 		if (hx <= 0xbfd2bec4) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ | ||
| 91 | 			k = 0; | ||
| 92 | 			c = 0; | ||
| 93 | 			f = x; | ||
| 94 | 		} | ||
| 95 | 	} else if (hx >= 0x7ff00000) | ||
| 96 | 		return x; | ||
| 97 | 	if (k) { | ||
| 98 | 		u.f = 1 + x; | ||
| 99 | 		hu = u.i>>32; | ||
| 100 | 		hu += 0x3ff00000 - 0x3fe6a09e; | ||
| 101 | 		k = (int)(hu>>20) - 0x3ff; | ||
| 102 | 		/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ | ||
| 103 | 		if (k < 54) { | ||
| 104 | 			c = k >= 2 ? 1-(u.f-x) : x-(u.f-1); | ||
| 105 | 			c /= u.f; | ||
| 106 | 		} else | ||
| 107 | 			c = 0; | ||
| 108 | 		/* reduce u into [sqrt(2)/2, sqrt(2)] */ | ||
| 109 | 		hu = (hu&0x000fffff) + 0x3fe6a09e; | ||
| 110 | 		u.i = (uint64_t)hu<<32 | (u.i&0xffffffff); | ||
| 111 | 		f = u.f - 1; | ||
| 112 | 	} | ||
| 113 | 	hfsq = 0.5*f*f; | ||
| 114 | 	s = f/(2.0+f); | ||
| 115 | 	z = s*s; | ||
| 116 | 	w = z*z; | ||
| 117 | 	t1 = w*(Lg2+w*(Lg4+w*Lg6)); | ||
| 118 | 	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); | ||
| 119 | 	R = t2 + t1; | ||
| 120 | 	dk = k; | ||
| 121 | 	return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi; | ||
| 122 | } | ||
lib/libc/musl/src/math/log1pf.c deleted-77| ... | @@ -1,77 +0,0 @@ | ||
| 1 | /* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */ | ||
| 2 | /* | ||
| 3 | * ==================================================== | ||
| 4 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | ||
| 5 | * | ||
| 6 | * Developed at SunPro, 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 | |||
| 13 | #include "libm.h" | ||
| 14 | |||
| 15 | static const float | ||
| 16 | ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ | ||
| 17 | ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ | ||
| 18 | /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ | ||
| 19 | Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ | ||
| 20 | Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ | ||
| 21 | Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ | ||
| 22 | Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ | ||
| 23 | |||
| 24 | float log1pf(float x) | ||
| 25 | { | ||
| 26 | 	union {float f; uint32_t i;} u = {x}; | ||
| 27 | 	float_t hfsq,f,c,s,z,R,w,t1,t2,dk; | ||
| 28 | 	uint32_t ix,iu; | ||
| 29 | 	int k; | ||
| 30 | |||
| 31 | 	ix = u.i; | ||
| 32 | 	k = 1; | ||
| 33 | 	if (ix < 0x3ed413d0 || ix>>31) { /* 1+x < sqrt(2)+ */ | ||
| 34 | 		if (ix >= 0xbf800000) { /* x <= -1.0 */ | ||
| 35 | 			if (x == -1) | ||
| 36 | 				return x/0.0f; /* log1p(-1)=+inf */ | ||
| 37 | 			return (x-x)/0.0f; /* log1p(x<-1)=NaN */ | ||
| 38 | 		} | ||
| 39 | 		if (ix<<1 < 0x33800000<<1) { /* |x| < 2**-24 */ | ||
| 40 | 			/* underflow if subnormal */ | ||
| 41 | 			if ((ix&0x7f800000) == 0) | ||
| 42 | 				FORCE_EVAL(x*x); | ||
| 43 | 			return x; | ||
| 44 | 		} | ||
| 45 | 		if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ | ||
| 46 | 			k = 0; | ||
| 47 | 			c = 0; | ||
| 48 | 			f = x; | ||
| 49 | 		} | ||
| 50 | 	} else if (ix >= 0x7f800000) | ||
| 51 | 		return x; | ||
| 52 | 	if (k) { | ||
| 53 | 		u.f = 1 + x; | ||
| 54 | 		iu = u.i; | ||
| 55 | 		iu += 0x3f800000 - 0x3f3504f3; | ||
| 56 | 		k = (int)(iu>>23) - 0x7f; | ||
| 57 | 		/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ | ||
| 58 | 		if (k < 25) { | ||
| 59 | 			c = k >= 2 ? 1-(u.f-x) : x-(u.f-1); | ||
| 60 | 			c /= u.f; | ||
| 61 | 		} else | ||
| 62 | 			c = 0; | ||
| 63 | 		/* reduce u into [sqrt(2)/2, sqrt(2)] */ | ||
| 64 | 		iu = (iu&0x007fffff) + 0x3f3504f3; | ||
| 65 | 		u.i = iu; | ||
| 66 | 		f = u.f - 1; | ||
| 67 | 	} | ||
| 68 | 	s = f/(2.0f + f); | ||
| 69 | 	z = s*s; | ||
| 70 | 	w = z*z; | ||
| 71 | 	t1= w*(Lg2+w*Lg4); | ||
| 72 | 	t2= z*(Lg1+w*Lg3); | ||
| 73 | 	R = t2 + t1; | ||
| 74 | 	hfsq = 0.5f*f*f; | ||
| 75 | 	dk = k; | ||
| 76 | 	return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi; | ||
| 77 | } | ||
lib/std/math/log1p.zig+13-19| ... | @@ -43,17 +43,14 @@ fn log1p_32(x: f32) f32 { | ... | @@ -43,17 +43,14 @@ fn log1p_32(x: f32) f32 { |
| 43 | 43 | ||
| 44 | // 1 + x < sqrt(2)+ | 44 | // 1 + x < sqrt(2)+ |
| 45 | if (ix < 0x3ED413D0 or ix >> 31 != 0) { | 45 | if (ix < 0x3ED413D0 or ix >> 31 != 0) { |
| 46 | // x <= -1.0 | 46 | // x = -1.0 |
| 47 | if (ix >= 0xBF800000) { | 47 | if (ix == 0xBF800000) |
| 48 | // log1p(-1) = -inf | 48 | // log1p(-1) = -inf |
| 49 | if (x == -1.0) { | 49 | return x / 0.0; |
| 50 | return -math.inf(f32); | 50 | // x < -1.0 |
| 51 | } | 51 | if (ix > 0xBF800000) |
| 52 | // log1p(x < -1) = nan | 52 | // log1p(x < -1) = nan |
| 53 | else { | 53 | return (x - x) / 0.0; |
| 54 | return math.nan(f32); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | // |x| < 2^(-24) | 54 | // |x| < 2^(-24) |
| 58 | if ((ix << 1) < (0x33800000 << 1)) { | 55 | if ((ix << 1) < (0x33800000 << 1)) { |
| 59 | // underflow if subnormal | 56 | // underflow if subnormal |
| ... | @@ -122,21 +119,18 @@ fn log1p_64(x: f64) f64 { | ... | @@ -122,21 +119,18 @@ fn log1p_64(x: f64) f64 { |
| 122 | 119 | ||
| 123 | // 1 + x < sqrt(2) | 120 | // 1 + x < sqrt(2) |
| 124 | if (hx < 0x3FDA827A or hx >> 31 != 0) { | 121 | if (hx < 0x3FDA827A or hx >> 31 != 0) { |
| 125 | // x <= -1.0 | 122 | // x = -1.0 |
| 126 | if (hx >= 0xBFF00000) { | 123 | if (ix == 0xBFF0000000000000) |
| 127 | // log1p(-1) = -inf | 124 | // log1p(-1) = -inf |
| 128 | if (x == -1.0) { | 125 | return x / 0.0; |
| 129 | return -math.inf(f64); | 126 | // x < -1.0 |
| 130 | } | 127 | if (hx >= 0xBFF00000) |
| 131 | // log1p(x < -1) = nan | 128 | // log1p(x < -1) = nan |
| 132 | else { | 129 | return (x - x) / 0.0; |
| 133 | return math.nan(f64); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | // |x| < 2^(-53) | 130 | // |x| < 2^(-53) |
| 137 | if ((hx << 1) < (0x3CA00000 << 1)) { | 131 | if ((hx << 1) < (0x3CA00000 << 1)) { |
| 138 | if ((hx & 0x7FF00000) == 0) { | 132 | if ((hx & 0x7FF00000) == 0) { |
| 139 | math.raiseUnderflow(); | 133 | mem.doNotOptimizeAway(@as(f32, @floatCast(x))); |
| 140 | } | 134 | } |
| 141 | return x; | 135 | return x; |
| 142 | } | 136 | } |
src/libs/musl.zig-4| ... | @@ -845,9 +845,7 @@ const src_files = [_][]const u8{ | ... | @@ -845,9 +845,7 @@ const src_files = [_][]const u8{ |
| 845 | "musl/src/math/i386/llrintf.c", | 845 | "musl/src/math/i386/llrintf.c", |
| 846 | "musl/src/math/i386/llrintl.c", | 846 | "musl/src/math/i386/llrintl.c", |
| 847 | "musl/src/math/i386/log10l.s", | 847 | "musl/src/math/i386/log10l.s", |
| 848 | "musl/src/math/i386/log1pf.s", | ||
| 849 | "musl/src/math/i386/log1pl.s", | 848 | "musl/src/math/i386/log1pl.s", |
| 850 | "musl/src/math/i386/log1p.s", | ||
| 851 | "musl/src/math/i386/log2l.s", | 849 | "musl/src/math/i386/log2l.s", |
| 852 | "musl/src/math/i386/logl.s", | 850 | "musl/src/math/i386/logl.s", |
| 853 | "musl/src/math/i386/remainder.c", | 851 | "musl/src/math/i386/remainder.c", |
| ... | @@ -887,8 +885,6 @@ const src_files = [_][]const u8{ | ... | @@ -887,8 +885,6 @@ const src_files = [_][]const u8{ |
| 887 | "musl/src/math/llroundf.c", | 885 | "musl/src/math/llroundf.c", |
| 888 | "musl/src/math/llroundl.c", | 886 | "musl/src/math/llroundl.c", |
| 889 | "musl/src/math/log10l.c", | 887 | "musl/src/math/log10l.c", |
| 890 | "musl/src/math/log1p.c", | ||
| 891 | "musl/src/math/log1pf.c", | ||
| 892 | "musl/src/math/log1pl.c", | 888 | "musl/src/math/log1pl.c", |
| 893 | "musl/src/math/log2l.c", | 889 | "musl/src/math/log2l.c", |
| 894 | "musl/src/math/logb.c", | 890 | "musl/src/math/logb.c", |
src/libs/wasi_libc.zig-2| ... | @@ -719,8 +719,6 @@ const libc_top_half_src_files = [_][]const u8{ | ... | @@ -719,8 +719,6 @@ const libc_top_half_src_files = [_][]const u8{ |
| 719 | "musl/src/math/llroundf.c", | 719 | "musl/src/math/llroundf.c", |
| 720 | "musl/src/math/llroundl.c", | 720 | "musl/src/math/llroundl.c", |
| 721 | "musl/src/math/log10l.c", | 721 | "musl/src/math/log10l.c", |
| 722 | "musl/src/math/log1p.c", | ||
| 723 | "musl/src/math/log1pf.c", | ||
| 724 | "musl/src/math/log1pl.c", | 722 | "musl/src/math/log1pl.c", |
| 725 | "musl/src/math/log2l.c", | 723 | "musl/src/math/log2l.c", |
| 726 | "musl/src/math/logb.c", | 724 | "musl/src/math/logb.c", |
test/libc.zig+2-2| ... | @@ -252,8 +252,8 @@ pub fn addCases(cases: *tests.LibcContext) void { | ... | @@ -252,8 +252,8 @@ pub fn addCases(cases: *tests.LibcContext) void { |
| 252 | cases.addLibcTestCase("math/log10.c", true, .{}); | 252 | cases.addLibcTestCase("math/log10.c", true, .{}); |
| 253 | cases.addLibcTestCase("math/log10f.c", true, .{}); | 253 | cases.addLibcTestCase("math/log10f.c", true, .{}); |
| 254 | cases.addLibcTestCase("math/log10l.c", true, .{}); | 254 | cases.addLibcTestCase("math/log10l.c", true, .{}); |
| 255 | // cases.addLibcTestCase("math/log1p.c", true, .{}); | 255 | cases.addLibcTestCase("math/log1p.c", true, .{}); |
| 256 | // cases.addLibcTestCase("math/log1pf.c", true, .{}); | 256 | cases.addLibcTestCase("math/log1pf.c", true, .{}); |
| 257 | // cases.addLibcTestCase("math/log1pl.c", true, .{}); | 257 | // cases.addLibcTestCase("math/log1pl.c", true, .{}); |
| 258 | cases.addLibcTestCase("math/log2.c", true, .{}); | 258 | cases.addLibcTestCase("math/log2.c", true, .{}); |
| 259 | cases.addLibcTestCase("math/log2f.c", true, .{}); | 259 | cases.addLibcTestCase("math/log2f.c", true, .{}); |