mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-04-14 19:58:46 +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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/log/backtrace.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* Aborts process after printing a backtrace.
|
||||
|
@ -32,13 +29,10 @@
|
|||
relegated wontreturn void __die(void) {
|
||||
static bool once;
|
||||
if (cmpxchg(&once, false, true)) {
|
||||
if (weaken(fflush)) {
|
||||
weaken(fflush)(NULL);
|
||||
}
|
||||
if (!IsTiny()) {
|
||||
if (IsDebuggerPresent(false)) DebugBreak();
|
||||
ShowBacktrace(2, NULL);
|
||||
}
|
||||
}
|
||||
_exit(77);
|
||||
exit(77);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sigbits.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
@ -34,9 +36,6 @@
|
|||
* @see also libc/oncrash.c
|
||||
*/
|
||||
|
||||
struct ucontext;
|
||||
struct siginfo;
|
||||
|
||||
static const int sigs[] = {
|
||||
SIGHUP, /* hangup aka ctrl_close_event */
|
||||
SIGINT, /* ctrl+c aka ^C aka ETX aka \003 aka ♥ */
|
||||
|
|
|
@ -36,9 +36,9 @@ copysign:
|
|||
.rodata.cst16
|
||||
.Lnan: .long 0xffffffff
|
||||
.long 0x7fffffff
|
||||
.long 0
|
||||
.long 0
|
||||
.Lneg0: .long 0
|
||||
.long -2147483648
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.Lneg0: .long 0x00000000
|
||||
.long 0x80000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.source __FILE__
|
||||
|
||||
// Returns cosine of 𝑥.
|
||||
//
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
// @param 𝑥 is double scalar in low half of %xmm0
|
||||
// @return double scalar in low half of %xmm0
|
||||
// @see pow(), exp()
|
||||
exp10:
|
||||
ezlea exp10l,ax
|
||||
exp10: ezlea exp10l,ax
|
||||
jmp _d2ld2
|
||||
.endfn exp10,globl
|
||||
.alias exp10,pow10
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.source __FILE__
|
||||
|
||||
// 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 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
/*-*- 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 2020 Justine Alexandra Roberts Tunney │
|
||||
│ 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 │
|
||||
|
@ -16,37 +16,8 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
|
||||
// Returns 𝑥^𝑦.
|
||||
//
|
||||
// @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
|
||||
long double __powl_finite(long double x, long double y) {
|
||||
return powl(x, y);
|
||||
}
|
|
@ -17,18 +17,23 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.source __FILE__
|
||||
|
||||
truncl: .profilable
|
||||
sub $24,%rsp
|
||||
fldt 32(%rsp)
|
||||
fnstcw 14(%rsp)
|
||||
movzwl 14(%rsp),%eax
|
||||
// Rounds to integer, toward zero.
|
||||
//
|
||||
// @param 𝑥 is long double passed on stack
|
||||
// @return long double in %st
|
||||
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
|
||||
mov %ax,12(%rsp)
|
||||
fldcw 12(%rsp)
|
||||
mov %ax,-4(%rbp)
|
||||
fldcw -4(%rbp)
|
||||
frndint
|
||||
fldcw 14(%rsp)
|
||||
add $24,%rsp
|
||||
fldcw -2(%rbp)
|
||||
leave
|
||||
ret
|
||||
.endfn truncl,globl
|
||||
|
|
|
@ -29,5 +29,6 @@
|
|||
char *xdtoal(long double d) {
|
||||
char *p = xmalloc(32);
|
||||
g_xfmt_p(p, &d, 16, 32, 2);
|
||||
/* g_xfmt_p(p, &d, 20, 32, 2); */
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
TEST(exp10l, test) {
|
||||
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("0", gc(xdtoal(exp10l(-INFINITY))));
|
||||
EXPECT_STREQ("NAN", gc(xdtoal(exp10l(NAN))));
|
||||
|
@ -38,6 +39,7 @@ TEST(exp10l, test) {
|
|||
TEST(exp10, test) {
|
||||
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("0", gc(xdtoa(exp10(-INFINITY))));
|
||||
EXPECT_STREQ("NAN", gc(xdtoa(exp10(NAN))));
|
||||
|
@ -48,6 +50,7 @@ TEST(exp10, test) {
|
|||
TEST(exp10f, test) {
|
||||
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("0", gc(xdtoaf(exp10f(-INFINITY))));
|
||||
EXPECT_STREQ("NAN", gc(xdtoaf(exp10f(NAN))));
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
@ -29,7 +31,12 @@
|
|||
#include "libc/testlib/testlib.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("-1", gc(xdtoal(powl(-1, 1.1))));
|
||||
|
@ -37,21 +44,143 @@ TEST(powl, testLongDouble) {
|
|||
EXPECT_STREQ("INFINITY", gc(xdtoal(powl(10, 4933))));
|
||||
EXPECT_STREQ("0", gc(xdtoal(powl(10, -5000))));
|
||||
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("-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_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_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) {
|
||||
|
|
|
@ -29,6 +29,7 @@ TEST_LIBC_TINYMATH_DIRECTDEPS = \
|
|||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RAND \
|
||||
LIBC_STDIO \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STR \
|
||||
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) {
|
||||
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,
|
||||
|
|
Loading…
Add table
Reference in a new issue