mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +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 ♥ */
|
||||
|
|
|
@ -7698,7 +7698,7 @@ imp '_memccpy' _memccpy ntdll 2198
|
|||
imp '_memicmp' _memicmp ntdll 2199
|
||||
imp '_onexit' _onexit KernelBase 1846
|
||||
imp '_purecall' _purecall KernelBase 1847
|
||||
imp 'sys__setjmp_nt' _setjmp ntdll 2200
|
||||
imp 'sys__setjmp_nt' _setjmp ntdll 2200
|
||||
imp '_setjmpex' _setjmpex ntdll 2201
|
||||
imp '_time64' _time64 KernelBase 1848
|
||||
imp '_wmakepath_s' _wmakepath_s ntdll 2245
|
||||
|
@ -7707,7 +7707,7 @@ imp '_wtoi' _wtoi ntdll 2247
|
|||
imp '_wtoi64' _wtoi64 ntdll 2248
|
||||
imp '_wtol' _wtol ntdll 2249
|
||||
imp 'sys_abs_nt' abs ntdll 2250
|
||||
imp '__sys_accept_nt' accept ws2_32 1
|
||||
imp '__sys_accept_nt' accept ws2_32 1
|
||||
imp 'sys_atan_nt' atan ntdll 2251
|
||||
imp 'sys_atan2_nt' atan2 ntdll 2252
|
||||
imp 'sys_atexit_nt' atexit KernelBase 1849
|
||||
|
@ -7718,12 +7718,12 @@ imp 'bDeleteLDC' bDeleteLDC gdi32 1949
|
|||
imp 'bInitSystemAndFontsDirectories' bInitSystemAndFontsDirectoriesW gdi32 1950
|
||||
imp 'bMakePathName' bMakePathNameW gdi32 1951
|
||||
imp '__sys_bind_nt' bind ws2_32 2 3
|
||||
imp 'sys_bsearch_nt' bsearch ntdll 2255
|
||||
imp 'sys_bsearch_nt' bsearch ntdll 2255
|
||||
imp 'bsearch_s' bsearch_s ntdll 2256
|
||||
imp 'cGetTTFFromFOT' cGetTTFFromFOT gdi32 1952
|
||||
imp 'sys_ceil_nt' ceil ntdll 2257
|
||||
imp '__sys_closesocket_nt' closesocket ws2_32 3 1
|
||||
imp '__sys_connect_nt' connect ws2_32 4
|
||||
imp '__sys_connect_nt' connect ws2_32 4
|
||||
imp 'sys_cos_nt' cos ntdll 2258
|
||||
imp 'dwLBSubclass' dwLBSubclass comdlg32 128
|
||||
imp 'dwOKSubclass' dwOKSubclass comdlg32 129
|
||||
|
@ -7745,7 +7745,7 @@ imp 'sys_gethostname_nt' gethostname ws2_32 57
|
|||
imp 'sys_getnameinfo_nt' getnameinfo ws2_32 192
|
||||
imp '__sys_getpeername_nt' getpeername ws2_32 5 3
|
||||
imp 'sys_getprotobyname_nt' getprotobyname ws2_32 53
|
||||
imp 'sys_getprotobynumber_nt' getprotobynumber ws2_32 54
|
||||
imp 'sys_getprotobynumber_nt' getprotobynumber ws2_32 54
|
||||
imp 'sys_getservbyname_nt' getservbyname ws2_32 55
|
||||
imp 'sys_getservbyport_nt' getservbyport ws2_32 56
|
||||
imp '__sys_getsockname_nt' getsockname ws2_32 6 3
|
||||
|
@ -7758,24 +7758,24 @@ imp '__sys_ioctlsocket_nt' ioctlsocket ws2_32 10 3
|
|||
imp 'iswascii' iswascii ntdll 2273
|
||||
imp 'keybd_event' keybd_event user32 2580
|
||||
imp 'sys_labs_nt' labs ntdll 2282
|
||||
imp '__sys_listen_nt' listen ws2_32 13 2
|
||||
imp '__sys_listen_nt' listen ws2_32 13 2
|
||||
imp 'sys_log_nt' log ntdll 2283
|
||||
imp 'sys_longjmp_nt' longjmp ntdll 2284
|
||||
imp 'sys_longjmp_nt' longjmp ntdll 2284
|
||||
imp 'mouse_event' mouse_event user32 2583
|
||||
imp 'pGdiDevCaps' pGdiDevCaps gdi32 1961
|
||||
imp 'pGdiSharedHandleTable' pGdiSharedHandleTable gdi32 1962
|
||||
imp 'pGdiSharedMemory' pGdiSharedMemory gdi32 1963
|
||||
imp 'pldcGet' pldcGet gdi32 1964
|
||||
imp 'sys_recv_nt' recv ws2_32 16
|
||||
imp '__sys_recvfrom_nt' recvfrom ws2_32 17
|
||||
imp '__sys_select_nt' select ws2_32 18 5
|
||||
imp '__sys_recvfrom_nt' recvfrom ws2_32 17
|
||||
imp '__sys_select_nt' select ws2_32 18 5
|
||||
imp 'semDxTrimNotification' semDxTrimNotification gdi32 1965
|
||||
imp 'sys_send_nt' send ws2_32 19
|
||||
imp '__sys_sendto_nt' sendto ws2_32 20
|
||||
imp '__sys_sendto_nt' sendto ws2_32 20
|
||||
imp '__sys_setsockopt_nt' setsockopt ws2_32 21 5
|
||||
imp '__sys_shutdown_nt' shutdown ws2_32 22 2
|
||||
imp '__sys_shutdown_nt' shutdown ws2_32 22 2
|
||||
imp 'sys_sin_nt' sin ntdll 2296
|
||||
imp '__sys_socket_nt' socket ws2_32 23
|
||||
imp '__sys_socket_nt' socket ws2_32 23
|
||||
imp 'timeBeginPeriod' timeBeginPeriod kernel32 1609
|
||||
imp 'timeEndPeriod' timeEndPeriod kernel32 1610
|
||||
imp 'timeGetDevCaps' timeGetDevCaps kernel32 1611
|
||||
|
|
|
@ -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…
Reference in a new issue