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
unzip cosmopolitan.zip
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 \
-o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds \
-include cosmopolitan.h crt.o ape.o cosmopolitan.a
@ -52,13 +52,13 @@ find o -name \*.com | xargs ls -rShal | less
## Support Vector
| Platform | Min Version | Circa |
| :--- | ---: | ---: |
| AMD | K8 Venus | 2005 |
| Intel | Core | 2006 |
| New Technology | Vista | 2006 |
| GNU/Systemd | 2.6.18 | 2007 |
| XNU's Not UNIX | 15.6 | 2018 |
| FreeBSD | 12 | 2018 |
| OpenBSD | 6.4 | 2018 |
| NetBSD | 9.1 | 2020 |
| Platform | Min Version | Circa |
| :--- | ---: | ---: |
| AMD | K8 Venus | 2005 |
| Intel | Core | 2006 |
| New Technology | Vista | 2006 |
| GNU/Systemd | 2.6.18 | 2007 |
| XNU's Not UNIX! | 15.6 | 2018 |
| FreeBSD | 12 | 2018 |
| OpenBSD | 6.4 | 2018 |
| 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("f2xm1" : "=t"(t) : "0"(t));
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) {
return 0;
} else if (!y) {

View file

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

View file

@ -39,7 +39,6 @@ void SetUp(void) {
TEST(powl, test) {
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("INFINITY", gc(xdtoal(powl(10, 4933))));
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, -(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) {
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("INFINITY", gc(xdtoa(pow(10, 309))));
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, -(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) {
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("INFINITY", gc(xdtoaf(powf(10, 39))));
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, -(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) {

View file

@ -7,7 +7,7 @@
81 3 // 27 = assert
2 8 ** 256 = assert
17 10 % 7 = assert
17 10 mod 7 = assert
17 10 fmod 7 = assert
# FLOATING POINT
.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, g, "abs", Abs, fabsl(x), "absolute value")
M(2, g, "min", Min, MIN(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, "min", Min, fminl(x, y), "pops two values and pushes minimum")
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, "rem", Remainder, remainderl(x, y), "float remainder")
M(2, g, "fmod", Fmod, fmodl(x, y), "trunc 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, "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, "ln2", Fldln2, M_LN2, "logₑ2")
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, "exp", Exp, expl(x), "𝑒ˣ")
M(1, g, "expm1", Expm1, expm1l(x), "𝑒ˣ-1")
M(1, g, "exp2", Exp2, exp2l(x), "")
M(1, g, "exp10", Exp10, exp10l(x), "10ˣ")
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, g, "log2", Log2, log2l(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, "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(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, "trunc", Trunc, truncl(x), "round towards zero")
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, "floor", Floor, floorl(x), "largest integral not greater than 𝑥")