Handle more pow cases (#61)

This commit is contained in:
Justine Tunney 2021-03-04 06:13:32 -08:00
parent 1a08594f95
commit 43b2475aaa
6 changed files with 45 additions and 21 deletions

View file

@ -25,7 +25,7 @@ five files to get started:
wget https://justine.lol/cosmopolitan/cosmopolitan.zip wget https://justine.lol/cosmopolitan/cosmopolitan.zip
unzip cosmopolitan.zip unzip cosmopolitan.zip
printf 'main() { printf("hello world\\n"); }\n' >hello.c printf 'main() { printf("hello world\\n"); }\n' >hello.c
gcc -g -Og -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \ gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
-fno-omit-frame-pointer -pg -mnop-mcount \ -fno-omit-frame-pointer -pg -mnop-mcount \
-o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds \ -o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds \
-include cosmopolitan.h crt.o ape.o cosmopolitan.a -include cosmopolitan.h crt.o ape.o cosmopolitan.a
@ -58,7 +58,7 @@ find o -name \*.com | xargs ls -rShal | less
| Intel | Core | 2006 | | Intel | Core | 2006 |
| New Technology | Vista | 2006 | | New Technology | Vista | 2006 |
| GNU/Systemd | 2.6.18 | 2007 | | GNU/Systemd | 2.6.18 | 2007 |
| XNU's Not UNIX | 15.6 | 2018 | | XNU's Not UNIX! | 15.6 | 2018 |
| FreeBSD | 12 | 2018 | | FreeBSD | 12 | 2018 |
| OpenBSD | 6.4 | 2018 | | OpenBSD | 6.4 | 2018 |
| NetBSD | 9.1 | 2020 | | NetBSD | 9.1 | 2020 |

View file

@ -31,7 +31,11 @@ long double powl(long double x, long double y) {
asm("fprem" : "=t"(t) : "0"(u), "u"(1.L)); asm("fprem" : "=t"(t) : "0"(u), "u"(1.L));
asm("f2xm1" : "=t"(t) : "0"(t)); asm("f2xm1" : "=t"(t) : "0"(t));
asm("fscale" : "=t"(t) : "0"(t + 1), "u"(u)); asm("fscale" : "=t"(t) : "0"(t + 1), "u"(u));
return copysignl(t, x); if (signbit(x)) {
if (y != truncl(y)) return -NAN;
if (!signbit(y) || ((int64_t)y & 1)) t = -t;
}
return t;
} else if (y > 0) { } else if (y > 0) {
return 0; return 0;
} else if (!y) { } else if (!y) {

View file

@ -406,6 +406,7 @@ TEST(sprintf, test_float) {
#ifndef __FINITE_MATH_ONLY__ #ifndef __FINITE_MATH_ONLY__
EXPECT_STREQ("nan", Format("%.4f", NAN)); EXPECT_STREQ("nan", Format("%.4f", NAN));
#endif #endif
EXPECT_STREQ("-0.0000", Format("%.4f", -0.));
EXPECT_STREQ("3.1415", Format("%.4f", 3.1415354)); EXPECT_STREQ("3.1415", Format("%.4f", 3.1415354));
EXPECT_STREQ("30343.142", Format("%.3f", 30343.1415354)); EXPECT_STREQ("30343.142", Format("%.3f", 30343.1415354));
EXPECT_STREQ("34", Format("%.0f", 34.1415354)); EXPECT_STREQ("34", Format("%.0f", 34.1415354));

View file

@ -39,7 +39,6 @@ void SetUp(void) {
TEST(powl, test) { TEST(powl, test) {
EXPECT_STREQ("27", gc(xdtoal(powl(3, 3)))); EXPECT_STREQ("27", gc(xdtoal(powl(3, 3))));
EXPECT_STREQ("-27", gc(xdtoal(powl(-3, 3)))); EXPECT_STREQ("-27", gc(xdtoal(powl(-3, 3))));
EXPECT_STREQ("-1", gc(xdtoal(powl(-1, 1.1))));
EXPECT_STREQ("1e+4932", gc(xdtoal(powl(10, 4932)))); EXPECT_STREQ("1e+4932", gc(xdtoal(powl(10, 4932))));
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(10, 4933)))); EXPECT_STREQ("INFINITY", gc(xdtoal(powl(10, 4933))));
EXPECT_STREQ("0", gc(xdtoal(powl(10, -5000)))); EXPECT_STREQ("0", gc(xdtoal(powl(10, -5000))));
@ -83,12 +82,15 @@ TEST(powl, test) {
EXPECT_STREQ("-INFINITY", gc(xdtoal(powl(-0., -(MAX(rando, 1) | 1))))); EXPECT_STREQ("-INFINITY", gc(xdtoal(powl(-0., -(MAX(rando, 1) | 1)))));
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(0, -(rando & -2))))); EXPECT_STREQ("INFINITY", gc(xdtoal(powl(0, -(rando & -2)))));
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(-0., -(rando & -2))))); EXPECT_STREQ("INFINITY", gc(xdtoal(powl(-0., -(rando & -2)))));
EXPECT_TRUE(isnan(powl(-3, 1. / MAX(rando, 2))));
EXPECT_TRUE(isnan(powl(-3, -(1. / MAX(rando, 2)))));
EXPECT_STREQ("-.3333333333333333", gc(xdtoal(powl(-3, -1))));
EXPECT_STREQ(".1111111111111111", gc(xdtoal(powl(-3, -2))));
} }
TEST(pow, test) { TEST(pow, test) {
EXPECT_STREQ("27", gc(xdtoa(pow(3, 3)))); EXPECT_STREQ("27", gc(xdtoa(pow(3, 3))));
EXPECT_STREQ("-27", gc(xdtoa(pow(-3, 3)))); EXPECT_STREQ("-27", gc(xdtoa(pow(-3, 3))));
EXPECT_STREQ("-1", gc(xdtoa(pow(-1, 1.1))));
EXPECT_STREQ("1e+308", gc(xdtoa(pow(10, 308)))); EXPECT_STREQ("1e+308", gc(xdtoa(pow(10, 308))));
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(10, 309)))); EXPECT_STREQ("INFINITY", gc(xdtoa(pow(10, 309))));
EXPECT_STREQ("0", gc(xdtoa(pow(10, -5000)))); EXPECT_STREQ("0", gc(xdtoa(pow(10, -5000))));
@ -132,12 +134,13 @@ TEST(pow, test) {
EXPECT_STREQ("-INFINITY", gc(xdtoa(pow(-0., -(MAX(rando, 1) | 1))))); EXPECT_STREQ("-INFINITY", gc(xdtoa(pow(-0., -(MAX(rando, 1) | 1)))));
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(0, -(rando & -2))))); EXPECT_STREQ("INFINITY", gc(xdtoa(pow(0, -(rando & -2)))));
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(-0., -(rando & -2))))); EXPECT_STREQ("INFINITY", gc(xdtoa(pow(-0., -(rando & -2)))));
EXPECT_STREQ("-.333333333333333", gc(xdtoa(pow(-3, -1))));
EXPECT_STREQ(".111111111111111", gc(xdtoa(pow(-3, -2))));
} }
TEST(powf, test) { TEST(powf, test) {
EXPECT_STREQ("27", gc(xdtoaf(powf(3, 3)))); EXPECT_STREQ("27", gc(xdtoaf(powf(3, 3))));
EXPECT_STREQ("-27", gc(xdtoaf(powf(-3, 3)))); EXPECT_STREQ("-27", gc(xdtoaf(powf(-3, 3))));
EXPECT_STREQ("-1", gc(xdtoaf(powf(-1, 1.1))));
EXPECT_STREQ("1e+38", gc(xdtoaf(powf(10, 38)))); EXPECT_STREQ("1e+38", gc(xdtoaf(powf(10, 38))));
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(10, 39)))); EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(10, 39))));
EXPECT_STREQ("0", gc(xdtoaf(powf(10, -5000)))); EXPECT_STREQ("0", gc(xdtoaf(powf(10, -5000))));
@ -181,6 +184,8 @@ TEST(powf, test) {
EXPECT_STREQ("-INFINITY", gc(xdtoaf(powf(-0., -(MAX(rando, 1) | 1))))); EXPECT_STREQ("-INFINITY", gc(xdtoaf(powf(-0., -(MAX(rando, 1) | 1)))));
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(0, -(rando & -2))))); EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(0, -(rando & -2)))));
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(-0., -(rando & -2))))); EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(-0., -(rando & -2)))));
EXPECT_STREQ("-.333333", gc(xdtoaf(powf(-3, -1))));
EXPECT_STREQ(".111111", gc(xdtoaf(powf(-3, -2))));
} }
BENCH(powl, bench) { BENCH(powl, bench) {

View file

@ -7,7 +7,7 @@
81 3 // 27 = assert 81 3 // 27 = assert
2 8 ** 256 = assert 2 8 ** 256 = assert
17 10 % 7 = assert 17 10 % 7 = assert
17 10 mod 7 = assert 17 10 fmod 7 = assert
# FLOATING POINT # FLOATING POINT
.1 .2 + .3 - abs epsilon < assert .1 .2 + .3 - abs epsilon < assert

View file

@ -29,11 +29,13 @@ M(1, i, "ungray", Ungray, ungray(x), "inverse gray coding")
M(1, i, "popcnt", Popcnt, Popcnt(x), "count bits") M(1, i, "popcnt", Popcnt, Popcnt(x), "count bits")
M(1, g, "abs", Abs, fabsl(x), "absolute value") M(1, g, "abs", Abs, fabsl(x), "absolute value")
M(2, g, "min", Min, MIN(x, y), "pops two values and pushes minimum") M(2, g, "min", Min, fminl(x, y), "pops two values and pushes minimum")
M(2, g, "max", Max, MAX(x, y), "pops two values and pushes maximum") M(2, g, "max", Max, fmaxl(x, y), "pops two values and pushes maximum")
M(2, g, "mod", Euclidean, emodl(x, y), "euclidean remainder") M(2, g, "fmod", Fmod, fmodl(x, y), "trunc remainder")
M(2, g, "rem", Remainder, remainderl(x, y), "float remainder") M(2, g, "emod", Emod, emodl(x, y), "euclidean remainder")
M(2, g, "remainder", Remainder, remainderl(x, y), "rint remainder")
M(2, g, "hypot", Hypot, hypotl(x, y), "euclidean distance")
M(0, i, "false", False, 0, "0") M(0, i, "false", False, 0, "0")
M(0, i, "true", True, 1, "1") M(0, i, "true", True, 1, "1")
@ -49,16 +51,21 @@ M(0, f, "l2t", Fldl2t, M_LOG2_10, "log₂10")
M(0, f, "lg2", Fldlg2, M_LOG10_2, "log₁₀2") M(0, f, "lg2", Fldlg2, M_LOG10_2, "log₁₀2")
M(0, f, "ln2", Fldln2, M_LN2, "logₑ2") M(0, f, "ln2", Fldln2, M_LN2, "logₑ2")
M(0, f, "l2e", Fldl2e, M_LOG2E, "logₑ10") M(0, f, "l2e", Fldl2e, M_LOG2E, "logₑ10")
M(2, f, "nextafter", Nextafter, nextafterl(x, y), "next ulp")
M(1, f, "significand", Significand, significandl(x), "mantissa")
M(1, f, "sqrt", Sqrt, sqrtl(x), "√𝑥") M(1, f, "sqrt", Sqrt, sqrtl(x), "√𝑥")
M(1, f, "exp", Exp, expl(x), "𝑒ˣ") M(1, f, "exp", Exp, expl(x), "𝑒ˣ")
M(1, g, "expm1", Expm1, expm1l(x), "𝑒ˣ-1")
M(1, g, "exp2", Exp2, exp2l(x), "") M(1, g, "exp2", Exp2, exp2l(x), "")
M(1, g, "exp10", Exp10, exp10l(x), "10ˣ") M(1, g, "exp10", Exp10, exp10l(x), "10ˣ")
M(2, g, "ldexp", Ldexp, ldexpl(x, y), "𝑥×") M(2, g, "ldexp", Ldexp, ldexpl(x, y), "𝑥×")
M(2, g, "scalb", Scalb, scalbl(x, y), "𝑥×")
M(1, f, "log", Log, logl(x), "logₑ𝑥") M(1, f, "log", Log, logl(x), "logₑ𝑥")
M(1, g, "log2", Log2, log2l(x), "log₂𝑥") M(1, g, "log2", Log2, log2l(x), "log₂𝑥")
M(1, g, "log10", Log10, log10l(x), "log₁₀𝑥") M(1, g, "log10", Log10, log10l(x), "log₁₀𝑥")
M(1, g, "ilogb", Ilogb, ilogbl(x), "exponent")
M(1, g, "sin", Sin, sinl(x), "sine") M(1, g, "sin", Sin, sinl(x), "sine")
M(1, g, "cos", Cos, cosl(x), "cosine") M(1, g, "cos", Cos, cosl(x), "cosine")
@ -68,10 +75,17 @@ M(1, g, "acos", Acos, acosl(x), "arccosine")
M(1, g, "atan", Atan, atanl(x), "arctangent") M(1, g, "atan", Atan, atanl(x), "arctangent")
M(2, g, "atan2", Atan2, atan2l(x, y), "arctangent of 𝑥/𝑦") M(2, g, "atan2", Atan2, atan2l(x, y), "arctangent of 𝑥/𝑦")
M(1, g, "sinh", Sinh, sinhl(x), "hyperbolic sine")
M(1, g, "cosh", Cosh, coshl(x), "hyperbolic cosine")
M(1, g, "tanh", Tanh, tanhl(x), "hyperbolic tangent")
M(1, g, "asinh", Asinh, asinhl(x), "hyperbolic arcsine")
M(1, g, "acosh", Acosh, acoshl(x), "hyperbolic arccosine")
M(1, g, "atanh", Atanh, atanhl(x), "hyperbolic arctangent")
M(1, g, "round", Round, roundl(x), "round away from zero") M(1, g, "round", Round, roundl(x), "round away from zero")
M(1, g, "trunc", Trunc, truncl(x), "round towards zero") M(1, g, "trunc", Trunc, truncl(x), "round towards zero")
M(1, g, "rint", Rint, rintl(x), "round to even") M(1, g, "rint", Rint, rintl(x), "round to even")
M(1, g, "nearbyint", Nearbyint, nearbyint(x), "round to nearest integer") M(1, g, "nearbyint", Nearbyint, nearbyintl(x), "round to nearest integer")
M(1, g, "ceil", Ceil, ceill(x), "smallest integral not less than 𝑥") M(1, g, "ceil", Ceil, ceill(x), "smallest integral not less than 𝑥")
M(1, g, "floor", Floor, floorl(x), "largest integral not greater than 𝑥") M(1, g, "floor", Floor, floorl(x), "largest integral not greater than 𝑥")