mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-04-16 11:54:58 +00:00
Make pow() conform to standard definition
This commit is contained in:
parent
754974faaa
commit
8af91bcbe7
15 changed files with 253 additions and 85 deletions
|
@ -17,12 +17,9 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/bits/weaken.h"
|
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/log/backtrace.internal.h"
|
#include "libc/log/backtrace.internal.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/runtime/runtime.h"
|
|
||||||
#include "libc/stdio/stdio.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aborts process after printing a backtrace.
|
* Aborts process after printing a backtrace.
|
||||||
|
@ -32,13 +29,10 @@
|
||||||
relegated wontreturn void __die(void) {
|
relegated wontreturn void __die(void) {
|
||||||
static bool once;
|
static bool once;
|
||||||
if (cmpxchg(&once, false, true)) {
|
if (cmpxchg(&once, false, true)) {
|
||||||
if (weaken(fflush)) {
|
|
||||||
weaken(fflush)(NULL);
|
|
||||||
}
|
|
||||||
if (!IsTiny()) {
|
if (!IsTiny()) {
|
||||||
if (IsDebuggerPresent(false)) DebugBreak();
|
if (IsDebuggerPresent(false)) DebugBreak();
|
||||||
ShowBacktrace(2, NULL);
|
ShowBacktrace(2, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_exit(77);
|
exit(77);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
#include "libc/calls/struct/siginfo.h"
|
||||||
|
#include "libc/calls/ucontext.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
@ -34,9 +36,6 @@
|
||||||
* @see also libc/oncrash.c
|
* @see also libc/oncrash.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ucontext;
|
|
||||||
struct siginfo;
|
|
||||||
|
|
||||||
static const int sigs[] = {
|
static const int sigs[] = {
|
||||||
SIGHUP, /* hangup aka ctrl_close_event */
|
SIGHUP, /* hangup aka ctrl_close_event */
|
||||||
SIGINT, /* ctrl+c aka ^C aka ETX aka \003 aka ♥ */
|
SIGINT, /* ctrl+c aka ^C aka ETX aka \003 aka ♥ */
|
||||||
|
|
|
@ -36,9 +36,9 @@ copysign:
|
||||||
.rodata.cst16
|
.rodata.cst16
|
||||||
.Lnan: .long 0xffffffff
|
.Lnan: .long 0xffffffff
|
||||||
.long 0x7fffffff
|
.long 0x7fffffff
|
||||||
.long 0
|
.long 0x00000000
|
||||||
.long 0
|
.long 0x00000000
|
||||||
.Lneg0: .long 0
|
.Lneg0: .long 0x00000000
|
||||||
.long -2147483648
|
.long 0x80000000
|
||||||
.long 0
|
.long 0x00000000
|
||||||
.long 0
|
.long 0x00000000
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
.source __FILE__
|
|
||||||
|
|
||||||
// Returns cosine of 𝑥.
|
// Returns cosine of 𝑥.
|
||||||
//
|
//
|
||||||
|
|
|
@ -23,8 +23,7 @@
|
||||||
// @param 𝑥 is double scalar in low half of %xmm0
|
// @param 𝑥 is double scalar in low half of %xmm0
|
||||||
// @return double scalar in low half of %xmm0
|
// @return double scalar in low half of %xmm0
|
||||||
// @see pow(), exp()
|
// @see pow(), exp()
|
||||||
exp10:
|
exp10: ezlea exp10l,ax
|
||||||
ezlea exp10l,ax
|
|
||||||
jmp _d2ld2
|
jmp _d2ld2
|
||||||
.endfn exp10,globl
|
.endfn exp10,globl
|
||||||
.alias exp10,pow10
|
.alias exp10,pow10
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
.source __FILE__
|
|
||||||
|
|
||||||
// Returns absolute value of 𝑥.
|
// Returns absolute value of 𝑥.
|
||||||
//
|
//
|
||||||
|
|
67
libc/tinymath/powl.c
Normal file
67
libc/tinymath/powl.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/math.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns 𝑥^𝑦.
|
||||||
|
*/
|
||||||
|
long double powl(long double x, long double y) {
|
||||||
|
long double t, u;
|
||||||
|
if (!isunordered(x, y)) {
|
||||||
|
if (!isinf(y)) {
|
||||||
|
if (!isinf(x)) {
|
||||||
|
if (x) {
|
||||||
|
asm("fyl2x" : "=t"(u) : "0"(fabsl(x)), "u"(y) : "st(1)");
|
||||||
|
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);
|
||||||
|
} else if (y > 0) {
|
||||||
|
return 0;
|
||||||
|
} else if (!y) {
|
||||||
|
return 1;
|
||||||
|
} else if (y == truncl(y) && ((int64_t)y & 1)) {
|
||||||
|
return copysignl(INFINITY, x);
|
||||||
|
} else {
|
||||||
|
return INFINITY;
|
||||||
|
}
|
||||||
|
} else if (signbit(x)) {
|
||||||
|
if (!y) return 1;
|
||||||
|
x = y < 0 ? 0 : INFINITY;
|
||||||
|
if (y == truncl(y) && ((int64_t)y & 1)) x = -x;
|
||||||
|
return x;
|
||||||
|
} else if (y < 0) {
|
||||||
|
return 0;
|
||||||
|
} else if (y > 0) {
|
||||||
|
return INFINITY;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x = fabsl(x);
|
||||||
|
if (x < 1) return signbit(y) ? INFINITY : 0;
|
||||||
|
if (x > 1) return signbit(y) ? 0 : INFINITY;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (!y || x == 1) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
@ -16,37 +16,8 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/runtime/pc.internal.h"
|
#include "libc/math.h"
|
||||||
#include "libc/macros.internal.h"
|
|
||||||
|
|
||||||
// Returns 𝑥^𝑦.
|
long double __powl_finite(long double x, long double y) {
|
||||||
//
|
return powl(x, y);
|
||||||
// @param 𝑥 is an 80-bit long double passed on stack in 16-bytes
|
}
|
||||||
// @param 𝑦 is the power, also pushed on stack, in reverse order
|
|
||||||
// @return result of exponentiation on FPU stack in %st
|
|
||||||
// @note Sun's fdlibm needs 2kLOC to do this for RISC lool
|
|
||||||
// @define z=y*log2(fabs(x)),copysign(trunc(exp2(fmod(z,1)))*exp2(z),x)
|
|
||||||
powl: push %rbp
|
|
||||||
mov %rsp,%rbp
|
|
||||||
.profilable
|
|
||||||
fldt 32(%rbp)
|
|
||||||
fldt 16(%rbp)
|
|
||||||
fxam
|
|
||||||
fstsw
|
|
||||||
fabs
|
|
||||||
fyl2x
|
|
||||||
fld1
|
|
||||||
fld %st(1)
|
|
||||||
fprem
|
|
||||||
f2xm1
|
|
||||||
faddp
|
|
||||||
fscale
|
|
||||||
fxch
|
|
||||||
fstp %st
|
|
||||||
test $FPU_C1>>8,%ah
|
|
||||||
jz 1f
|
|
||||||
fchs
|
|
||||||
1: pop %rbp
|
|
||||||
ret
|
|
||||||
.endfn powl,globl
|
|
||||||
.alias powl,__powl_finite
|
|
|
@ -17,18 +17,23 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
.source __FILE__
|
|
||||||
|
|
||||||
truncl: .profilable
|
// Rounds to integer, toward zero.
|
||||||
sub $24,%rsp
|
//
|
||||||
fldt 32(%rsp)
|
// @param 𝑥 is long double passed on stack
|
||||||
fnstcw 14(%rsp)
|
// @return long double in %st
|
||||||
movzwl 14(%rsp),%eax
|
truncl: pushq %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
sub $16,%rsp
|
||||||
|
fnstcw -2(%rbp)
|
||||||
|
fldt 16(%rbp)
|
||||||
|
movzwl -2(%rbp),%eax
|
||||||
or $0b1100,%ah # round to zero
|
or $0b1100,%ah # round to zero
|
||||||
mov %ax,12(%rsp)
|
mov %ax,-4(%rbp)
|
||||||
fldcw 12(%rsp)
|
fldcw -4(%rbp)
|
||||||
frndint
|
frndint
|
||||||
fldcw 14(%rsp)
|
fldcw -2(%rbp)
|
||||||
add $24,%rsp
|
leave
|
||||||
ret
|
ret
|
||||||
.endfn truncl,globl
|
.endfn truncl,globl
|
||||||
|
|
|
@ -29,5 +29,6 @@
|
||||||
char *xdtoal(long double d) {
|
char *xdtoal(long double d) {
|
||||||
char *p = xmalloc(32);
|
char *p = xmalloc(32);
|
||||||
g_xfmt_p(p, &d, 16, 32, 2);
|
g_xfmt_p(p, &d, 16, 32, 2);
|
||||||
|
/* g_xfmt_p(p, &d, 20, 32, 2); */
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
TEST(exp10l, test) {
|
TEST(exp10l, test) {
|
||||||
EXPECT_STREQ("1", gc(xdtoal(exp10l(0))));
|
EXPECT_STREQ("1", gc(xdtoal(exp10l(0))));
|
||||||
EXPECT_STREQ("1", gc(xdtoal(exp10l(-0.))));
|
EXPECT_STREQ("1", gc(xdtoal(exp10l(-0.))));
|
||||||
|
EXPECT_STREQ(".01", gc(xdtoal(exp10l(-2.))));
|
||||||
EXPECT_STREQ("INFINITY", gc(xdtoal(exp10l(INFINITY))));
|
EXPECT_STREQ("INFINITY", gc(xdtoal(exp10l(INFINITY))));
|
||||||
EXPECT_STREQ("0", gc(xdtoal(exp10l(-INFINITY))));
|
EXPECT_STREQ("0", gc(xdtoal(exp10l(-INFINITY))));
|
||||||
EXPECT_STREQ("NAN", gc(xdtoal(exp10l(NAN))));
|
EXPECT_STREQ("NAN", gc(xdtoal(exp10l(NAN))));
|
||||||
|
@ -38,6 +39,7 @@ TEST(exp10l, test) {
|
||||||
TEST(exp10, test) {
|
TEST(exp10, test) {
|
||||||
EXPECT_STREQ("1", gc(xdtoa(exp10(0))));
|
EXPECT_STREQ("1", gc(xdtoa(exp10(0))));
|
||||||
EXPECT_STREQ("1", gc(xdtoa(exp10(-0.))));
|
EXPECT_STREQ("1", gc(xdtoa(exp10(-0.))));
|
||||||
|
EXPECT_STREQ(".01", gc(xdtoa(exp10(-2.))));
|
||||||
EXPECT_STREQ("INFINITY", gc(xdtoa(exp10(INFINITY))));
|
EXPECT_STREQ("INFINITY", gc(xdtoa(exp10(INFINITY))));
|
||||||
EXPECT_STREQ("0", gc(xdtoa(exp10(-INFINITY))));
|
EXPECT_STREQ("0", gc(xdtoa(exp10(-INFINITY))));
|
||||||
EXPECT_STREQ("NAN", gc(xdtoa(exp10(NAN))));
|
EXPECT_STREQ("NAN", gc(xdtoa(exp10(NAN))));
|
||||||
|
@ -48,6 +50,7 @@ TEST(exp10, test) {
|
||||||
TEST(exp10f, test) {
|
TEST(exp10f, test) {
|
||||||
EXPECT_STREQ("1", gc(xdtoaf(exp10f(0))));
|
EXPECT_STREQ("1", gc(xdtoaf(exp10f(0))));
|
||||||
EXPECT_STREQ("1", gc(xdtoaf(exp10f(-0.))));
|
EXPECT_STREQ("1", gc(xdtoaf(exp10f(-0.))));
|
||||||
|
EXPECT_STREQ(".01", gc(xdtoaf(exp10f(-2.))));
|
||||||
EXPECT_STREQ("INFINITY", gc(xdtoaf(exp10f(INFINITY))));
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(exp10f(INFINITY))));
|
||||||
EXPECT_STREQ("0", gc(xdtoaf(exp10f(-INFINITY))));
|
EXPECT_STREQ("0", gc(xdtoaf(exp10f(-INFINITY))));
|
||||||
EXPECT_STREQ("NAN", gc(xdtoaf(exp10f(NAN))));
|
EXPECT_STREQ("NAN", gc(xdtoaf(exp10f(NAN))));
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/calls/struct/siginfo.h"
|
#include "libc/calls/struct/siginfo.h"
|
||||||
#include "libc/calls/ucontext.h"
|
#include "libc/calls/ucontext.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
|
#include "libc/rand/rand.h"
|
||||||
#include "libc/runtime/gc.h"
|
#include "libc/runtime/gc.h"
|
||||||
#include "libc/runtime/pc.internal.h"
|
#include "libc/runtime/pc.internal.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
|
@ -29,7 +31,12 @@
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
TEST(powl, testLongDouble) {
|
int rando;
|
||||||
|
void SetUp(void) {
|
||||||
|
rando = rand() & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
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("-1", gc(xdtoal(powl(-1, 1.1))));
|
||||||
|
@ -37,21 +44,143 @@ TEST(powl, testLongDouble) {
|
||||||
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))));
|
||||||
EXPECT_STREQ("1.063382396627933e+37", gc(xdtoal(powl(2, 123))));
|
EXPECT_STREQ("1.063382396627933e+37", gc(xdtoal(powl(2, 123))));
|
||||||
EXPECT_STARTSWITH(".4248496805467504", gc(xdtoal(powl(0.7, 2.4))));
|
EXPECT_STARTSWITH(".4248496805467504", gc(xdtoal(powl(.7, 2.4))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(1, NAN))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(1, rando))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(NAN, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(rando, 0))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(0, 1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(0, 2))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(0, 2.1))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(-1, INFINITY))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(-1, -INFINITY))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(1. / MAX(2, rando), -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(1.1, -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(MAX(2, rando), -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(1. / MAX(2, rando), INFINITY))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(MAX(2, rando), INFINITY))));
|
||||||
|
EXPECT_STREQ("-0", gc(xdtoal(powl(-INFINITY, -1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(-INFINITY, -1.1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(-INFINITY, -2))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(-INFINITY, -2.1))));
|
||||||
|
EXPECT_STREQ("-0", gc(xdtoal(powl(-INFINITY, -3))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(-INFINITY, -3.1))));
|
||||||
|
EXPECT_STREQ("-INFINITY", gc(xdtoal(powl(-INFINITY, 1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(-INFINITY, 1.1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(-INFINITY, 2))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(-INFINITY, 2.1))));
|
||||||
|
EXPECT_STREQ("-INFINITY", gc(xdtoal(powl(-INFINITY, 3))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(-INFINITY, 3.1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(INFINITY, -1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoal(powl(INFINITY, -.1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(INFINITY, 1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(INFINITY, .1))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(INFINITY, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(INFINITY, -0.))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(0, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoal(powl(0, -0.))));
|
||||||
|
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)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(powl, testDouble) {
|
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_STARTSWITH(".42484968054675", gc(xdtoa(pow(0.7, 2.4))));
|
EXPECT_STREQ("0", gc(xdtoa(pow(10, -5000))));
|
||||||
|
EXPECT_STREQ("1.06338239662793e+37", gc(xdtoa(pow(2, 123))));
|
||||||
|
EXPECT_STARTSWITH(".42484968054675", gc(xdtoa(pow(.7, 2.4))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(1, NAN))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(1, rando))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(NAN, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(rando, 0))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(0, 1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(0, 2))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(0, 2.1))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(-1, INFINITY))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(-1, -INFINITY))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(1. / MAX(2, rando), -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(1.1, -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(MAX(2, rando), -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(1. / MAX(2, rando), INFINITY))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(MAX(2, rando), INFINITY))));
|
||||||
|
EXPECT_STREQ("-0", gc(xdtoa(pow(-INFINITY, -1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(-INFINITY, -1.1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(-INFINITY, -2))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(-INFINITY, -2.1))));
|
||||||
|
EXPECT_STREQ("-0", gc(xdtoa(pow(-INFINITY, -3))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(-INFINITY, -3.1))));
|
||||||
|
EXPECT_STREQ("-INFINITY", gc(xdtoa(pow(-INFINITY, 1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(-INFINITY, 1.1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(-INFINITY, 2))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(-INFINITY, 2.1))));
|
||||||
|
EXPECT_STREQ("-INFINITY", gc(xdtoa(pow(-INFINITY, 3))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(-INFINITY, 3.1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(INFINITY, -1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoa(pow(INFINITY, -.1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(INFINITY, 1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoa(pow(INFINITY, .1))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(INFINITY, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(INFINITY, -0.))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(0, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoa(pow(0, -0.))));
|
||||||
|
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)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(powl, testFloat) {
|
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_STARTSWITH(".4248496", gc(xdtoa(powf(0.7f, 2.4f))));
|
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))));
|
||||||
|
EXPECT_STREQ("1.06338e+37", gc(xdtoaf(powf(2, 123))));
|
||||||
|
EXPECT_STARTSWITH(".42485", gc(xdtoaf(powf(.7, 2.4))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(1, NAN))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(1, rando))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(NAN, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(rando, 0))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(0, 1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(0, 2))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(0, 2.1))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(-1, INFINITY))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(-1, -INFINITY))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(1. / MAX(2, rando), -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(1.1, -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(MAX(2, rando), -INFINITY))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(1. / MAX(2, rando), INFINITY))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(MAX(2, rando), INFINITY))));
|
||||||
|
EXPECT_STREQ("-0", gc(xdtoaf(powf(-INFINITY, -1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(-INFINITY, -1.1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(-INFINITY, -2))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(-INFINITY, -2.1))));
|
||||||
|
EXPECT_STREQ("-0", gc(xdtoaf(powf(-INFINITY, -3))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(-INFINITY, -3.1))));
|
||||||
|
EXPECT_STREQ("-INFINITY", gc(xdtoaf(powf(-INFINITY, 1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(-INFINITY, 1.1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(-INFINITY, 2))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(-INFINITY, 2.1))));
|
||||||
|
EXPECT_STREQ("-INFINITY", gc(xdtoaf(powf(-INFINITY, 3))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(-INFINITY, 3.1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(INFINITY, -1))));
|
||||||
|
EXPECT_STREQ("0", gc(xdtoaf(powf(INFINITY, -.1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(INFINITY, 1))));
|
||||||
|
EXPECT_STREQ("INFINITY", gc(xdtoaf(powf(INFINITY, .1))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(INFINITY, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(INFINITY, -0.))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(0, 0))));
|
||||||
|
EXPECT_STREQ("1", gc(xdtoaf(powf(0, -0.))));
|
||||||
|
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)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
BENCH(powl, bench) {
|
BENCH(powl, bench) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ TEST_LIBC_TINYMATH_DIRECTDEPS = \
|
||||||
LIBC_MEM \
|
LIBC_MEM \
|
||||||
LIBC_NEXGEN32E \
|
LIBC_NEXGEN32E \
|
||||||
LIBC_RAND \
|
LIBC_RAND \
|
||||||
|
LIBC_STDIO \
|
||||||
LIBC_RUNTIME \
|
LIBC_RUNTIME \
|
||||||
LIBC_STR \
|
LIBC_STR \
|
||||||
LIBC_STUBS \
|
LIBC_STUBS \
|
||||||
|
|
|
@ -171,7 +171,8 @@ static long double fyl2xp1(long double x, long double y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static long double fscale(long double significand, long double exponent) {
|
static long double fscale(long double significand, long double exponent) {
|
||||||
return scalbl(trunc(significand), exponent);
|
if (isunordered(significand, exponent)) return NAN;
|
||||||
|
return ldexp(significand, exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long double x87remainder(long double x, long double y, uint32_t *sw,
|
static long double x87remainder(long double x, long double y, uint32_t *sw,
|
||||||
|
|
Loading…
Add table
Reference in a new issue