Add more libm unit tests and fixes

See #61
This commit is contained in:
Justine Tunney 2021-03-02 13:57:23 -08:00
parent 32e289b1d8
commit 9367253b4d
15 changed files with 390 additions and 124 deletions

View file

@ -17,28 +17,41 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__
// Returns smallest integral not less than 𝑥.
//
// @param 𝑥 is double scalar in low half of %xmm0
// @return double scalar in low half of %xmm0
// @see round(),rint(),nearbyint()
// @see vroundsd $_MM_FROUND_TO_POS_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0
ceil: .leafprologue ceil: .leafprologue
.profilable .profilable
movsd nan(%rip),%xmm1 movsd 4f(%rip),%xmm3
movsd sig(%rip),%xmm2 movsd 2f(%rip),%xmm4
andpd %xmm0,%xmm1 movapd %xmm0,%xmm2
comisd %xmm1,%xmm2 movapd %xmm0,%xmm1
andpd %xmm3,%xmm2
ucomisd %xmm2,%xmm4
jbe 1f jbe 1f
cvttsd2siq %xmm0,%rax cvttsd2siq %xmm0,%rax
pxor %xmm1,%xmm1 pxor %xmm2,%xmm2
movsd one(%rip),%xmm2 movsd 3f(%rip),%xmm4
cvtsi2sdq %rax,%xmm1 andnpd %xmm1,%xmm3
cmpnlesd %xmm1,%xmm0 cvtsi2sdq %rax,%xmm2
andpd %xmm2,%xmm0 cmpnlesd %xmm2,%xmm0
addsd %xmm1,%xmm0 andpd %xmm4,%xmm0
addsd %xmm2,%xmm0
orpd %xmm3,%xmm0
1: .leafepilogue 1: .leafepilogue
.endfn ceil,globl .endfn ceil,globl
.rodata.cst8 .rodata.cst8
nan: .double nan 2: .long 0x00000000
sig: .quad 0x0010000000000000 .long 0x43300000
one: .double 1 3: .long 0x00000000
.long 0x3ff00000
// vroundsd $_MM_FROUND_TO_POS_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0 .rodata.cst16
4: .long 0xffffffff
.long 0x7fffffff
.long 0x00000000
.long 0x00000000

View file

@ -17,34 +17,39 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__
// Returns smallest integral not less than 𝑥.
//
// @param 𝑥 is float scalar in low quarter of %xmm0
// @return float scalar in low quarter of %xmm0
// @see round(),rint(),nearbyint()
// @see vroundss $_MM_FROUND_TO_POS_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0
ceilf: .leafprologue ceilf: .leafprologue
.profilable .profilable
movss .L3(%rip),%xmm1 movss 4f(%rip),%xmm3
andps %xmm0,%xmm1 movss 2f(%rip),%xmm4
movss .L2(%rip),%xmm2 movaps %xmm0,%xmm2
comiss %xmm1,%xmm2 movaps %xmm0,%xmm1
andps %xmm3,%xmm2
ucomiss %xmm2,%xmm4
jbe 1f jbe 1f
cvttss2si %xmm0,%eax cvttss2sil %xmm0,%eax
pxor %xmm1,%xmm1 pxor %xmm2,%xmm2
movss .L1(%rip),%xmm2 movss 3f(%rip),%xmm4
cvtsi2ss %eax,%xmm1 andnps %xmm1,%xmm3
cmpnless %xmm1,%xmm0 cvtsi2ssl %eax,%xmm2
andps %xmm2,%xmm0 cmpnless %xmm2,%xmm0
addss %xmm1,%xmm0 andps %xmm4,%xmm0
addss %xmm2,%xmm0
orps %xmm3,%xmm0
1: .leafepilogue 1: .leafepilogue
.endfn ceilf,globl .endfn ceilf,globl
.rodata.cst4 .rodata.cst4
.L1: .float 1.0 2: .long 0x4b000000
.L2: .long 1258291200 3: .long 0x3f800000
.rodata.cst16 .rodata.cst16
.L3: .long 2147483647 4: .long 0x7fffffff
.long 0 .long 0x00000000
.long 0 .long 0x00000000
.long 0 .long 0x00000000
// TODO(jart):
// vroundss $10,%xmm0,%xmm0,%xmm0

View file

@ -17,19 +17,24 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__
ceill: .profilable // Returns smallest integral not less than 𝑥.
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 ceill: pushq %rbp
andb $-13,%ah mov %rsp,%rbp
orb $8,%ah .profilable
movw %ax,12(%rsp) sub $16,%rsp
fldcw 12(%rsp) fnstcw -2(%rbp)
fldt 16(%rbp)
movzwl -2(%rbp),%eax
and $-13,%ah
or $8,%ah
mov %ax,-4(%rbp)
fldcw -4(%rbp)
frndint frndint
fldcw 14(%rsp) fldcw -2(%rbp)
add $24,%rsp leave
ret ret
.endfn ceill,globl .endfn ceill,globl

View file

@ -17,31 +17,42 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__
// vroundsd $_MM_FROUND_TO_NEG_INF|_MM_FROUND_NO_EXC,%xmm0,%xmm0,%xmm0
// Returns largest integral not greater than 𝑥.
//
// @param 𝑥 is double scalar in low half of %xmm0
// @return double scalar in low half of %xmm0
floor: .leafprologue floor: .leafprologue
.profilable .profilable
movsd 4f(%rip),%xmm1 movsd 4f(%rip),%xmm3
movsd 3f(%rip),%xmm2 movsd 2f(%rip),%xmm4
andpd %xmm0,%xmm1 movapd %xmm0,%xmm2
comisd %xmm1,%xmm2 movapd %xmm0,%xmm1
andpd %xmm3,%xmm2
ucomisd %xmm2,%xmm4
jbe 1f jbe 1f
cvttsd2siq %xmm0,%rax cvttsd2siq %xmm0,%rax
pxor %xmm1,%xmm1 pxor %xmm2,%xmm2
movsd 2f(%rip),%xmm2 movsd 3f(%rip),%xmm4
cvtsi2sdq %rax,%xmm1 andnpd %xmm1,%xmm3
movapd %xmm1,%xmm3 cvtsi2sdq %rax,%xmm2
cmpnlesd %xmm0,%xmm3 movapd %xmm2,%xmm5
movapd %xmm3,%xmm0 cmpnlesd %xmm0,%xmm5
andpd %xmm2,%xmm0 movapd %xmm5,%xmm0
subsd %xmm0,%xmm1 andpd %xmm4,%xmm0
movapd %xmm1,%xmm0 subsd %xmm0,%xmm2
movapd %xmm2,%xmm0
orpd %xmm3,%xmm0
1: .leafepilogue 1: .leafepilogue
.endfn floor,globl .endfn floor,globl
.rodata.cst8 .rodata.cst8
2: .double 1 2: .long 0x00000000
3: .quad 0x0010000000000000 .long 0x43300000
4: .double nan 3: .long 0x00000000
.long 0x3ff00000
.rodata.cst16
4: .long 0xffffffff
.long 0x7fffffff
.long 0x00000000
.long 0x00000000

View file

@ -17,31 +17,40 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__
// Returns largest integral not greater than 𝑥.
//
// @param 𝑥 is float scalar in low quarter of %xmm0
// @return float scalar in low quarter of %xmm0
floorf: .leafprologue floorf: .leafprologue
.profilable .profilable
movss .LC8(%rip),%xmm1 movss 4f(%rip),%xmm3
andps %xmm0,%xmm1 movss 2f(%rip),%xmm4
movss .LC7(%rip),%xmm2 movaps %xmm0,%xmm2
comiss %xmm1,%xmm2 movaps %xmm0,%xmm1
andps %xmm3,%xmm2
ucomiss %xmm2,%xmm4
jbe 1f jbe 1f
cvttss2si %xmm0,%eax cvttss2sil %xmm0,%eax
pxor %xmm1,%xmm1 pxor %xmm2,%xmm2
movss .LC3(%rip),%xmm2 movss 3f(%rip),%xmm4
cvtsi2ss %eax,%xmm1 andnps %xmm1,%xmm3
movaps %xmm1,%xmm3 cvtsi2ssl %eax,%xmm2
cmpnless %xmm0,%xmm3 movaps %xmm2,%xmm5
movaps %xmm3,%xmm0 cmpnless %xmm0,%xmm5
andps %xmm2,%xmm0 movaps %xmm5,%xmm0
subss %xmm0,%xmm1 andps %xmm4,%xmm0
movaps %xmm1,%xmm0 subss %xmm0,%xmm2
movaps %xmm2,%xmm0
orps %xmm3,%xmm0
1: .leafepilogue 1: .leafepilogue
.endfn floorf,globl .endfn floorf,globl
.rodata.cst4 .rodata.cst4
.LC3: .float 1.0 2: .long 0x4b000000
.LC7: .long 0x4b000000 3: .long 0x3f800000
.rodata.cst16 .rodata.cst16
.LC8: .long 2147483647,0,0,0 4: .long 0x7fffffff
.long 0x00000000
.long 0x00000000
.long 0x00000000

View file

@ -17,17 +17,23 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__
floorl: .profilable // Returns largest integral not greater than 𝑥.
fldt 8(%rsp) //
mov $7,%al // @param 𝑥 is long double passed on stack
fstcw 8(%rsp) // @return float scalar in low quarter of %xmm0
mov 9(%rsp),%ah floorl: pushq %rbp
mov %al,9(%rsp) mov %rsp,%rbp
fldcw 8(%rsp) sub $16,%rsp
fnstcw -2(%rbp)
fldt 16(%rbp)
movzwl -2(%rbp),%eax
and $-13,%ah
or $4,%ah
mov %ax,-4(%rbp)
fldcw -4(%rbp)
frndint frndint
mov %ah,9(%rsp) fldcw -2(%rbp)
fldcw 8(%rsp) leave
ret ret
.endfn floorl,globl .endfn floorl,globl

View file

@ -16,6 +16,7 @@
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/macros.internal.h" #include "libc/macros.internal.h"
// Returns 𝑥^𝑦. // Returns 𝑥^𝑦.
@ -24,12 +25,15 @@
// @param 𝑦 is the power, also pushed on stack, in reverse order // @param 𝑦 is the power, also pushed on stack, in reverse order
// @return result of exponentiation on FPU stack in %st // @return result of exponentiation on FPU stack in %st
// @note Sun's fdlibm needs 2kLOC to do this for RISC lool // @note Sun's fdlibm needs 2kLOC to do this for RISC lool
// @define exp2l(fmodl(y*log2l(x),1))*exp2l(y) // @define z=y*log2(fabs(x)),copysign(trunc(exp2(fmod(z,1)))*exp2(z),x)
powl: push %rbp powl: push %rbp
mov %rsp,%rbp mov %rsp,%rbp
.profilable .profilable
fldt 32(%rbp) fldt 32(%rbp)
fldt 16(%rbp) fldt 16(%rbp)
fxam
fstsw
fabs
fyl2x fyl2x
fld1 fld1
fld %st(1) fld %st(1)
@ -39,7 +43,10 @@ powl: push %rbp
fscale fscale
fxch fxch
fstp %st fstp %st
pop %rbp test $FPU_C1>>8,%ah
jz 1f
fchs
1: pop %rbp
ret ret
.endfn powl,globl .endfn powl,globl
.alias powl,__powl_finite .alias powl,__powl_finite

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__
// Rounds to integer, toward zero. // Rounds to integer, toward zero.
// //
@ -28,17 +27,26 @@
// @see roundsd $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0 // @see roundsd $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0
trunc: .leafprologue trunc: .leafprologue
.profilable .profilable
movsd 3f(%rip),%xmm1 movsd 3f(%rip),%xmm2
movsd 2f(%rip),%xmm2 movsd 2f(%rip),%xmm4
andpd %xmm0,%xmm1 movapd %xmm0,%xmm3
comisd %xmm1,%xmm2 movapd %xmm0,%xmm1
andpd %xmm2,%xmm3
ucomisd %xmm3,%xmm4
jbe 1f jbe 1f
cvttsd2siq %xmm0,%rax cvttsd2siq %xmm0,%rax
pxor %xmm0,%xmm0 pxor %xmm0,%xmm0
andnpd %xmm1,%xmm2
cvtsi2sdq %rax,%xmm0 cvtsi2sdq %rax,%xmm0
orpd %xmm2,%xmm0
1: .leafepilogue 1: .leafepilogue
.endfn trunc,globl .endfn trunc,globl
.rodata.cst8 .rodata.cst8
2: .quad 0x0010000000000000 2: .long 0x00000000
3: .double nan .long 0x43300000
.rodata.cst16
3: .long 0xffffffff
.long 0x7fffffff
.long 0x00000000
.long 0x00000000

View file

@ -17,18 +17,28 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__
// Rounds to integer, toward zero.
//
// @param 𝑥 is float scalar in low quarter of %xmm0
// @return float scalar in low quarter of %xmm0
// @define trunc(𝑥+copysign(.5,𝑥))
// @see round(),rint(),nearbyint()
// @see roundss $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0
truncf: .leafprologue truncf: .leafprologue
.profilable .profilable
movss 3f(%rip),%xmm1 movss 3f(%rip),%xmm2
andps %xmm0,%xmm1 movss 2f(%rip),%xmm4
movss 2f(%rip),%xmm2 movaps %xmm0,%xmm3
comiss %xmm1,%xmm2 movaps %xmm0,%xmm1
andps %xmm2,%xmm3
ucomiss %xmm3,%xmm4
jbe 1f jbe 1f
cvttss2si %xmm0,%eax cvttss2sil %xmm0,%eax
pxor %xmm0,%xmm0 pxor %xmm0,%xmm0
cvtsi2ss %eax,%xmm0 andnps %xmm1,%xmm2
cvtsi2ssl %eax,%xmm0
orps %xmm2,%xmm0
1: .leafepilogue 1: .leafepilogue
.endfn truncf,globl .endfn truncf,globl
@ -36,6 +46,3 @@ truncf: .leafprologue
2: .long 0x4b000000 2: .long 0x4b000000
.rodata.cst16 .rodata.cst16
3: .long 0x7fffffff,0,0,0 3: .long 0x7fffffff,0,0,0
// TODO(jart)
// roundss $_MM_FROUND_TO_ZERO|_MM_FROUND_NO_EXC,%xmm0,%xmm0

View file

@ -0,0 +1,55 @@
/*-*- 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"
#include "libc/runtime/gc.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(ceil, test) {
EXPECT_STREQ("3", gc(xdtoa(ceil(3))));
EXPECT_STREQ("4", gc(xdtoa(ceil(3.14))));
EXPECT_STREQ("-3", gc(xdtoa(ceil(-3.14))));
EXPECT_STREQ("-0", gc(xdtoa(ceil(-0.))));
EXPECT_STREQ("NAN", gc(xdtoa(ceil(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(ceil(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(ceil(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(ceil(-INFINITY))));
}
TEST(ceilf, test) {
EXPECT_STREQ("3", gc(xdtoaf(ceilf(3))));
EXPECT_STREQ("4", gc(xdtoaf(ceilf(3.14))));
EXPECT_STREQ("-3", gc(xdtoaf(ceilf(-3.14))));
EXPECT_STREQ("-0", gc(xdtoaf(ceilf(-0.))));
EXPECT_STREQ("NAN", gc(xdtoaf(ceilf(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoaf(ceilf(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoaf(ceilf(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoaf(ceilf(-INFINITY))));
}
TEST(ceill, test) {
EXPECT_STREQ("3", gc(xdtoal(ceill(3))));
EXPECT_STREQ("4", gc(xdtoal(ceill(3.14))));
EXPECT_STREQ("-3", gc(xdtoal(ceill(-3.14))));
EXPECT_STREQ("-0", gc(xdtoal(ceill(-0.))));
EXPECT_STREQ("NAN", gc(xdtoal(ceill(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoal(ceill(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoal(ceill(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoal(ceill(-INFINITY))));
}

View file

@ -0,0 +1,28 @@
/*-*- 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"
#include "libc/runtime/gc.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(exp2l, test) {
EXPECT_STREQ("16", gc(xdtoal(exp2l(4))));
EXPECT_STREQ("16", gc(xdtoa(exp2(4))));
EXPECT_STREQ("16", gc(xdtoaf(exp2f(4))));
}

View file

@ -0,0 +1,55 @@
/*-*- 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"
#include "libc/runtime/gc.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(floor, test) {
EXPECT_STREQ("3", gc(xdtoa(floor(3))));
EXPECT_STREQ("3", gc(xdtoa(floor(3.14))));
EXPECT_STREQ("-4", gc(xdtoa(floor(-3.14))));
EXPECT_STREQ("-0", gc(xdtoa(floor(-0.))));
EXPECT_STREQ("NAN", gc(xdtoa(floor(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(floor(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(floor(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(floor(-INFINITY))));
}
TEST(floorf, test) {
EXPECT_STREQ("3", gc(xdtoaf(floorf(3))));
EXPECT_STREQ("3", gc(xdtoaf(floorf(3.14))));
EXPECT_STREQ("-4", gc(xdtoaf(floorf(-3.14))));
EXPECT_STREQ("-0", gc(xdtoaf(floorf(-0.))));
EXPECT_STREQ("NAN", gc(xdtoaf(floorf(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoaf(floorf(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoaf(floorf(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoaf(floorf(-INFINITY))));
}
TEST(floorl, test) {
EXPECT_STREQ("3", gc(xdtoal(floorl(3))));
EXPECT_STREQ("3", gc(xdtoal(floorl(3.14))));
EXPECT_STREQ("-4", gc(xdtoal(floorl(-3.14))));
EXPECT_STREQ("-0", gc(xdtoal(floorl(-0.))));
EXPECT_STREQ("NAN", gc(xdtoal(floorl(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoal(floorl(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoal(floorl(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoal(floorl(-INFINITY))));
}

View file

@ -22,33 +22,35 @@
#include "libc/math.h" #include "libc/math.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/sysv/consts/sa.h" #include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "libc/x/x.h" #include "libc/x/x.h"
double powa(double x, double y) {
return exp2(fmod(y * log2(x), 1)) * exp2(y);
}
TEST(powl, testLongDouble) { TEST(powl, testLongDouble) {
EXPECT_TRUE(isnan(powl(-1, 1.1))); 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))));
EXPECT_STREQ("1.063382396627933e+37", gc(xdtoal(powl(2, 123)))); EXPECT_STREQ("1.063382396627933e+37", gc(xdtoal(powl(2, 123))));
/* .4248496805467504836322459796959084815827285786480897 */
EXPECT_STARTSWITH(".4248496805467504", gc(xdtoal(powl(0.7, 2.4)))); EXPECT_STARTSWITH(".4248496805467504", gc(xdtoal(powl(0.7, 2.4))));
} }
TEST(powl, testDouble) { TEST(powl, testDouble) {
EXPECT_STREQ("27", gc(xdtoa(pow(3, 3))));
EXPECT_STREQ("-27", gc(xdtoa(pow(-3, 3))));
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_STARTSWITH(".42484968054675", gc(xdtoa(pow(0.7, 2.4))));
} }
TEST(powl, testFloat) { TEST(powl, testFloat) {
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_STARTSWITH(".4248496", gc(xdtoa(powf(0.7f, 2.4f))));
} }

View file

@ -0,0 +1,55 @@
/*-*- 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"
#include "libc/runtime/gc.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(trunc, test) {
EXPECT_STREQ("3", gc(xdtoa(trunc(3))));
EXPECT_STREQ("3", gc(xdtoa(trunc(3.14))));
EXPECT_STREQ("-3", gc(xdtoa(trunc(-3.14))));
EXPECT_STREQ("-0", gc(xdtoa(trunc(-0.))));
EXPECT_STREQ("NAN", gc(xdtoa(trunc(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(trunc(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(trunc(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(trunc(-INFINITY))));
}
TEST(truncf, test) {
EXPECT_STREQ("3", gc(xdtoaf(truncf(3))));
EXPECT_STREQ("3", gc(xdtoaf(truncf(3.14))));
EXPECT_STREQ("-3", gc(xdtoaf(truncf(-3.14))));
EXPECT_STREQ("-0", gc(xdtoaf(truncf(-0.))));
EXPECT_STREQ("NAN", gc(xdtoaf(truncf(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoaf(truncf(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoaf(truncf(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoaf(truncf(-INFINITY))));
}
TEST(truncl, test) {
EXPECT_STREQ("3", gc(xdtoal(truncl(3))));
EXPECT_STREQ("3", gc(xdtoal(truncl(3.14))));
EXPECT_STREQ("-3", gc(xdtoal(truncl(-3.14))));
EXPECT_STREQ("-0", gc(xdtoal(truncl(-0.))));
EXPECT_STREQ("NAN", gc(xdtoal(truncl(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoal(truncl(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoal(truncl(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoal(truncl(-INFINITY))));
}

View file

@ -171,7 +171,7 @@ 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(significand, exponent); return scalbl(trunc(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,