xref: /minix3/tests/lib/libm/t_exp.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* $NetBSD: t_exp.c,v 1.8 2014/10/07 16:53:44 gson Exp $ */
211be35a1SLionel Sambuc 
311be35a1SLionel Sambuc /*-
411be35a1SLionel Sambuc  * Copyright (c) 2011 The NetBSD Foundation, Inc.
511be35a1SLionel Sambuc  * All rights reserved.
611be35a1SLionel Sambuc  *
711be35a1SLionel Sambuc  * This code is derived from software contributed to The NetBSD Foundation
811be35a1SLionel Sambuc  * by Jukka Ruohonen.
911be35a1SLionel Sambuc  *
1011be35a1SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
1111be35a1SLionel Sambuc  * modification, are permitted provided that the following conditions
1211be35a1SLionel Sambuc  * are met:
1311be35a1SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
1411be35a1SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
1511be35a1SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
1611be35a1SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
1711be35a1SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
1811be35a1SLionel Sambuc  *
1911be35a1SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2011be35a1SLionel Sambuc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2111be35a1SLionel Sambuc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2211be35a1SLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2311be35a1SLionel Sambuc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2411be35a1SLionel Sambuc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2511be35a1SLionel Sambuc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2611be35a1SLionel Sambuc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2711be35a1SLionel Sambuc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2811be35a1SLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2911be35a1SLionel Sambuc  * POSSIBILITY OF SUCH DAMAGE.
3011be35a1SLionel Sambuc  */
3111be35a1SLionel Sambuc 
3211be35a1SLionel Sambuc #include <atf-c.h>
3311be35a1SLionel Sambuc #include <math.h>
34*0a6a1f1dSLionel Sambuc #include "t_libm.h"
3511be35a1SLionel Sambuc 
3611be35a1SLionel Sambuc /* y = exp(x) */
3711be35a1SLionel Sambuc static const struct {
3811be35a1SLionel Sambuc 	double x;
3911be35a1SLionel Sambuc 	double y;
4011be35a1SLionel Sambuc 	double e;
4111be35a1SLionel Sambuc } exp_values[] = {
4211be35a1SLionel Sambuc 	{  -10, 0.4539992976248485e-4, 1e-4, },
4311be35a1SLionel Sambuc 	{   -5, 0.6737946999085467e-2, 1e-2, },
4411be35a1SLionel Sambuc 	{   -1, 0.3678794411714423,    1e-1, },
4511be35a1SLionel Sambuc 	{ -0.1, 0.9048374180359595,    1e-1, },
4611be35a1SLionel Sambuc 	{    0, 1.0000000000000000,    1,    },
4711be35a1SLionel Sambuc 	{  0.1, 1.1051709180756477,    1,    },
4811be35a1SLionel Sambuc 	{    1, 2.7182818284590452,    1,    },
4911be35a1SLionel Sambuc 	{    5, 148.41315910257660,    1e2, },
5011be35a1SLionel Sambuc 	{   10, 22026.465794806718,    1e4, },
5111be35a1SLionel Sambuc };
5211be35a1SLionel Sambuc 
5311be35a1SLionel Sambuc /*
54*0a6a1f1dSLionel Sambuc  * exp2/exp2f(3)
5511be35a1SLionel Sambuc  */
56*0a6a1f1dSLionel Sambuc ATF_LIBM_TEST(exp2_is_nan, "Test exp2(x) == NaN")
5711be35a1SLionel Sambuc {
58*0a6a1f1dSLionel Sambuc #ifdef T_LIBM_NAN
59*0a6a1f1dSLionel Sambuc 	T_LIBM_CHECK_NAN(0, exp2, T_LIBM_NAN);
60*0a6a1f1dSLionel Sambuc 	T_LIBM_CHECK_NAN(0, exp2f, T_LIBM_NAN);
61*0a6a1f1dSLionel Sambuc #else
62*0a6a1f1dSLionel Sambuc 	atf_tc_skip("no NaN on this machine");
6311be35a1SLionel Sambuc #endif
6411be35a1SLionel Sambuc }
6511be35a1SLionel Sambuc 
66*0a6a1f1dSLionel Sambuc ATF_LIBM_TEST(exp2_is_plus_zero, "Test exp2(x) == +0.0")
6711be35a1SLionel Sambuc {
68*0a6a1f1dSLionel Sambuc #ifdef T_LIBM_MINUS_INF
69*0a6a1f1dSLionel Sambuc 	T_LIBM_CHECK_PLUS_ZERO(0, exp2, T_LIBM_MINUS_INF);
70*0a6a1f1dSLionel Sambuc 	T_LIBM_CHECK_PLUS_ZERO(0, exp2f, T_LIBM_MINUS_INF);
71*0a6a1f1dSLionel Sambuc #else
72*0a6a1f1dSLionel Sambuc 	atf_tc_skip("no +/-Inf on this machine");
7311be35a1SLionel Sambuc #endif
7411be35a1SLionel Sambuc }
7511be35a1SLionel Sambuc 
76*0a6a1f1dSLionel Sambuc ATF_LIBM_TEST(exp2_powers, "Test exp2(x) is correct for some integer x")
7711be35a1SLionel Sambuc {
78*0a6a1f1dSLionel Sambuc 	static const struct {
79*0a6a1f1dSLionel Sambuc 		double	x;
80*0a6a1f1dSLionel Sambuc 		double	d_y;
81*0a6a1f1dSLionel Sambuc 		double	f_y;
82*0a6a1f1dSLionel Sambuc 	} v[] = {
83*0a6a1f1dSLionel Sambuc 	    { +0.0,	1.0,	1.0 },
84*0a6a1f1dSLionel Sambuc 	    { -0.0,	1.0,	1.0 },
85*0a6a1f1dSLionel Sambuc 	    {    1,	0x1p1,	0x1p1 },
86*0a6a1f1dSLionel Sambuc 	    {    2,	0x1p2,	0x1p2 },
87*0a6a1f1dSLionel Sambuc 	    {  100,	0x1p100,	0x1p100 },
88*0a6a1f1dSLionel Sambuc 	    {  125,	0x1p125,	0x1p125 },
89*0a6a1f1dSLionel Sambuc 	    {  126,	0x1p126,	0x1p126 },
90*0a6a1f1dSLionel Sambuc #if __DBL_MAX_EXP__ > 129
91*0a6a1f1dSLionel Sambuc 	    {  127,	0x1p127,	0x1p127 },
9211be35a1SLionel Sambuc #endif
93*0a6a1f1dSLionel Sambuc #ifdef T_LIBM_PLUS_INF
94*0a6a1f1dSLionel Sambuc 	    {  128,	0x1p128,	T_LIBM_PLUS_INF },
95*0a6a1f1dSLionel Sambuc 	    {  129,	0x1p129,	T_LIBM_PLUS_INF },
96*0a6a1f1dSLionel Sambuc 	    { 1000,	0x1p1000,	T_LIBM_PLUS_INF },
97*0a6a1f1dSLionel Sambuc 	    { 1020,	0x1p1020,	T_LIBM_PLUS_INF },
98*0a6a1f1dSLionel Sambuc 	    { 1023,	0x1p1023,	T_LIBM_PLUS_INF },
99*0a6a1f1dSLionel Sambuc 	    { 1024,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
100*0a6a1f1dSLionel Sambuc 	    { 1030,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
101*0a6a1f1dSLionel Sambuc 	    { 1050,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
102*0a6a1f1dSLionel Sambuc 	    { 2000,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
103*0a6a1f1dSLionel Sambuc 	    { 16383,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
104*0a6a1f1dSLionel Sambuc 	    { 16384,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
105*0a6a1f1dSLionel Sambuc 	    { 16385,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
10611be35a1SLionel Sambuc #endif
107*0a6a1f1dSLionel Sambuc 	    {   -1,	0x1p-1,	0x1p-1 },
108*0a6a1f1dSLionel Sambuc 	    {   -2,	0x1p-2,	0x1p-2 },
109*0a6a1f1dSLionel Sambuc 	    { -100,	0x1p-100,	0x1p-100 },
110*0a6a1f1dSLionel Sambuc 	    { -127,	0x1p-127,	0x1p-127 },
111*0a6a1f1dSLionel Sambuc 	    { -128,	0x1p-128,	0x1p-128 },
112*0a6a1f1dSLionel Sambuc #if __LDBL_MIN_EXP__ < -129
113*0a6a1f1dSLionel Sambuc 	    { -300,	0x1p-300,	0.0},
114*0a6a1f1dSLionel Sambuc 	    { -400,	0x1p-400,	0.0},
115*0a6a1f1dSLionel Sambuc 	    {-1000,	0x1p-1000,	0.0},
116*0a6a1f1dSLionel Sambuc 	    {-1022,	0x1p-1022,	0.0},
117*0a6a1f1dSLionel Sambuc 	    /* These should be denormal numbers */
118*0a6a1f1dSLionel Sambuc 	    {-1023,	0x1p-1023,	0.0},
119*0a6a1f1dSLionel Sambuc 	    {-1024,	0x1p-1024,	0.0},
120*0a6a1f1dSLionel Sambuc 	    {-1040,	0x1p-1040,	0.0},
121*0a6a1f1dSLionel Sambuc 	    {-1060,	0x1p-1060,	0.0},
122*0a6a1f1dSLionel Sambuc 	    /* This is the smallest result gcc will allow */
123*0a6a1f1dSLionel Sambuc 	    {-1074,	0x1p-1074,	0.0},
12411be35a1SLionel Sambuc #endif
125*0a6a1f1dSLionel Sambuc 	    {-1075,	0x0,	0.0},
126*0a6a1f1dSLionel Sambuc 	    {-1080,	0x0,	0.0},
127*0a6a1f1dSLionel Sambuc 	    {-2000,	0x0,	0.0},
128*0a6a1f1dSLionel Sambuc 	    {-16382,	0x0,	0.0},
129*0a6a1f1dSLionel Sambuc 	    {-16383,	0x0,	0.0},
130*0a6a1f1dSLionel Sambuc 	    {-16384,	0x0,	0.0},
131*0a6a1f1dSLionel Sambuc 	};
132*0a6a1f1dSLionel Sambuc 	unsigned int i;
133*0a6a1f1dSLionel Sambuc 
134*0a6a1f1dSLionel Sambuc 	for (i = 0; i < __arraycount(v); i++) {
135*0a6a1f1dSLionel Sambuc 		T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, 0.0);
136*0a6a1f1dSLionel Sambuc 		T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, 0.0);
137*0a6a1f1dSLionel Sambuc 	}
13811be35a1SLionel Sambuc }
13911be35a1SLionel Sambuc 
140*0a6a1f1dSLionel Sambuc ATF_LIBM_TEST(exp2_values, "Test exp2(x) is correct for some x")
14111be35a1SLionel Sambuc {
142*0a6a1f1dSLionel Sambuc 	static const struct {
143*0a6a1f1dSLionel Sambuc 		double	x;
144*0a6a1f1dSLionel Sambuc 		double	d_y;
145*0a6a1f1dSLionel Sambuc 		float   f_y;
146*0a6a1f1dSLionel Sambuc 		double	d_eps;
147*0a6a1f1dSLionel Sambuc 		double	f_eps;
148*0a6a1f1dSLionel Sambuc 	} v[] = {
149*0a6a1f1dSLionel Sambuc #if __DBL_MAX_EXP__ > 128
150*0a6a1f1dSLionel Sambuc 	    /* The largest double constant */
151*0a6a1f1dSLionel Sambuc 	    { 0x1.fffffffffffffp9,	0x1.ffffffffffd3ap1023,	0.00,
152*0a6a1f1dSLionel Sambuc 		0x1p969,	0.0 },
153*0a6a1f1dSLionel Sambuc 	    /* The largest float constant */
154*0a6a1f1dSLionel Sambuc 	    { 0x1.fffffep6,	0x1.ffff4ep+127,	0x1.ffff4ep+127,	6e30,	0.0 },
15511be35a1SLionel Sambuc #endif
156*0a6a1f1dSLionel Sambuc #ifdef T_LIBM_PLUS_INF
157*0a6a1f1dSLionel Sambuc 	    { T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF,	0.0,	0.0 },
15811be35a1SLionel Sambuc #endif
159*0a6a1f1dSLionel Sambuc 
160*0a6a1f1dSLionel Sambuc 	    /* The few values from the old tests */
161*0a6a1f1dSLionel Sambuc 	    /* Results from i386/amd64, d_eps needed on i386 */
162*0a6a1f1dSLionel Sambuc 	    /* f_y values calculated using py-mpmath */
163*0a6a1f1dSLionel Sambuc 	    {  1.1,	0x1.125fbee250664p+1,	0x1.125fc0p+1,	0x1p-52,	0x1.8p-22 },
164*0a6a1f1dSLionel Sambuc 	    {  2.2,	0x1.2611186bae675p+2,	0x1.26111ap+2,	0x1p-51,	0x1.8p-21 },
165*0a6a1f1dSLionel Sambuc 	    {  3.3,	0x1.3b2c47bff8328p+3,	0x1.3b2c48p+3,	0x1p-50,	0x1.8p-20 },
166*0a6a1f1dSLionel Sambuc 	    {  4.4,	0x1.51cb453b9536ep+4,	0x1.51cb46p+4,	0x1p-49,	0x1.8p-19 },
167*0a6a1f1dSLionel Sambuc 	    {  5.5,	0x1.6a09e667f3bcdp+5,	0x1.6a09e6p+5,	0x1p-48,	0x1.8p-18 },
168*0a6a1f1dSLionel Sambuc 	    {  6.6,	0x1.8406003b2ae5bp+6,	0x1.8405fep+6,	0x1p-47,	0x1.8p-17 },
169*0a6a1f1dSLionel Sambuc 	    {  7.7,	0x1.9fdf8bcce533ep+7,	0x1.9fdf88p+7,	0x1p-46,	0x1.8p-16 },
170*0a6a1f1dSLionel Sambuc 	    {  8.8,	0x1.bdb8cdadbe124p+8,	0x1.bdb8d2p+8,	0x1p-45,	0x1.8p-15 },
171*0a6a1f1dSLionel Sambuc 	};
172*0a6a1f1dSLionel Sambuc 	unsigned int i;
173*0a6a1f1dSLionel Sambuc 
174*0a6a1f1dSLionel Sambuc 	for (i = 0; i < __arraycount(v); i++) {
175*0a6a1f1dSLionel Sambuc 		T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, v[i].d_eps);
176*0a6a1f1dSLionel Sambuc 		if (i > 1)
177*0a6a1f1dSLionel Sambuc 			T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, v[i].f_eps);
178*0a6a1f1dSLionel Sambuc 	}
17911be35a1SLionel Sambuc }
18011be35a1SLionel Sambuc 
18111be35a1SLionel Sambuc 
18211be35a1SLionel Sambuc /*
18311be35a1SLionel Sambuc  * exp(3)
18411be35a1SLionel Sambuc  */
18511be35a1SLionel Sambuc ATF_TC(exp_nan);
ATF_TC_HEAD(exp_nan,tc)18611be35a1SLionel Sambuc ATF_TC_HEAD(exp_nan, tc)
18711be35a1SLionel Sambuc {
18811be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test exp(NaN) == NaN");
18911be35a1SLionel Sambuc }
19011be35a1SLionel Sambuc 
ATF_TC_BODY(exp_nan,tc)19111be35a1SLionel Sambuc ATF_TC_BODY(exp_nan, tc)
19211be35a1SLionel Sambuc {
19311be35a1SLionel Sambuc 	const double x = 0.0L / 0.0L;
19411be35a1SLionel Sambuc 
19511be35a1SLionel Sambuc 	if (isnan(exp(x)) == 0)
19611be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("exp(NaN) != NaN");
19711be35a1SLionel Sambuc }
19811be35a1SLionel Sambuc 
19911be35a1SLionel Sambuc ATF_TC(exp_inf_neg);
ATF_TC_HEAD(exp_inf_neg,tc)20011be35a1SLionel Sambuc ATF_TC_HEAD(exp_inf_neg, tc)
20111be35a1SLionel Sambuc {
20211be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test exp(-Inf) == +0.0");
20311be35a1SLionel Sambuc }
20411be35a1SLionel Sambuc 
ATF_TC_BODY(exp_inf_neg,tc)20511be35a1SLionel Sambuc ATF_TC_BODY(exp_inf_neg, tc)
20611be35a1SLionel Sambuc {
20711be35a1SLionel Sambuc 	const double x = -1.0L / 0.0L;
20811be35a1SLionel Sambuc 	double y = exp(x);
20911be35a1SLionel Sambuc 
21011be35a1SLionel Sambuc 	if (fabs(y) > 0.0 || signbit(y) != 0)
21111be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("exp(-Inf) != +0.0");
21211be35a1SLionel Sambuc }
21311be35a1SLionel Sambuc 
21411be35a1SLionel Sambuc ATF_TC(exp_inf_pos);
ATF_TC_HEAD(exp_inf_pos,tc)21511be35a1SLionel Sambuc ATF_TC_HEAD(exp_inf_pos, tc)
21611be35a1SLionel Sambuc {
21711be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test exp(+Inf) == +Inf");
21811be35a1SLionel Sambuc }
21911be35a1SLionel Sambuc 
ATF_TC_BODY(exp_inf_pos,tc)22011be35a1SLionel Sambuc ATF_TC_BODY(exp_inf_pos, tc)
22111be35a1SLionel Sambuc {
22211be35a1SLionel Sambuc 	const double x = 1.0L / 0.0L;
22311be35a1SLionel Sambuc 	double y = exp(x);
22411be35a1SLionel Sambuc 
22511be35a1SLionel Sambuc 	if (isinf(y) == 0 || signbit(y) != 0)
22611be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("exp(+Inf) != +Inf");
22711be35a1SLionel Sambuc }
22811be35a1SLionel Sambuc 
22911be35a1SLionel Sambuc ATF_TC(exp_product);
ATF_TC_HEAD(exp_product,tc)23011be35a1SLionel Sambuc ATF_TC_HEAD(exp_product, tc)
23111be35a1SLionel Sambuc {
23211be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test some selected exp(x)");
23311be35a1SLionel Sambuc }
23411be35a1SLionel Sambuc 
ATF_TC_BODY(exp_product,tc)23511be35a1SLionel Sambuc ATF_TC_BODY(exp_product, tc)
23611be35a1SLionel Sambuc {
23711be35a1SLionel Sambuc 	double eps;
23811be35a1SLionel Sambuc 	double x;
23911be35a1SLionel Sambuc 	double y;
24011be35a1SLionel Sambuc 	size_t i;
24111be35a1SLionel Sambuc 
24211be35a1SLionel Sambuc 	for (i = 0; i < __arraycount(exp_values); i++) {
24311be35a1SLionel Sambuc 		x = exp_values[i].x;
24411be35a1SLionel Sambuc 		y = exp_values[i].y;
24511be35a1SLionel Sambuc 		eps = 1e-15 * exp_values[i].e;
24611be35a1SLionel Sambuc 
24711be35a1SLionel Sambuc 		if (fabs(exp(x) - y) > eps)
24811be35a1SLionel Sambuc 			atf_tc_fail_nonfatal("exp(%0.01f) != %18.18e", x, y);
24911be35a1SLionel Sambuc 	}
25011be35a1SLionel Sambuc }
25111be35a1SLionel Sambuc 
25211be35a1SLionel Sambuc ATF_TC(exp_zero_neg);
ATF_TC_HEAD(exp_zero_neg,tc)25311be35a1SLionel Sambuc ATF_TC_HEAD(exp_zero_neg, tc)
25411be35a1SLionel Sambuc {
25511be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test exp(-0.0) == 1.0");
25611be35a1SLionel Sambuc }
25711be35a1SLionel Sambuc 
ATF_TC_BODY(exp_zero_neg,tc)25811be35a1SLionel Sambuc ATF_TC_BODY(exp_zero_neg, tc)
25911be35a1SLionel Sambuc {
26011be35a1SLionel Sambuc 	const double x = -0.0L;
26111be35a1SLionel Sambuc 
26211be35a1SLionel Sambuc 	if (fabs(exp(x) - 1.0) > 0.0)
26311be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("exp(-0.0) != 1.0");
26411be35a1SLionel Sambuc }
26511be35a1SLionel Sambuc 
26611be35a1SLionel Sambuc ATF_TC(exp_zero_pos);
ATF_TC_HEAD(exp_zero_pos,tc)26711be35a1SLionel Sambuc ATF_TC_HEAD(exp_zero_pos, tc)
26811be35a1SLionel Sambuc {
26911be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test exp(+0.0) == 1.0");
27011be35a1SLionel Sambuc }
27111be35a1SLionel Sambuc 
ATF_TC_BODY(exp_zero_pos,tc)27211be35a1SLionel Sambuc ATF_TC_BODY(exp_zero_pos, tc)
27311be35a1SLionel Sambuc {
27411be35a1SLionel Sambuc 	const double x = 0.0L;
27511be35a1SLionel Sambuc 
27611be35a1SLionel Sambuc 	if (fabs(exp(x) - 1.0) > 0.0)
27711be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("exp(+0.0) != 1.0");
27811be35a1SLionel Sambuc }
27911be35a1SLionel Sambuc 
28011be35a1SLionel Sambuc /*
28111be35a1SLionel Sambuc  * expf(3)
28211be35a1SLionel Sambuc  */
28311be35a1SLionel Sambuc ATF_TC(expf_nan);
ATF_TC_HEAD(expf_nan,tc)28411be35a1SLionel Sambuc ATF_TC_HEAD(expf_nan, tc)
28511be35a1SLionel Sambuc {
28611be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expf(NaN) == NaN");
28711be35a1SLionel Sambuc }
28811be35a1SLionel Sambuc 
ATF_TC_BODY(expf_nan,tc)28911be35a1SLionel Sambuc ATF_TC_BODY(expf_nan, tc)
29011be35a1SLionel Sambuc {
29111be35a1SLionel Sambuc 	const float x = 0.0L / 0.0L;
29211be35a1SLionel Sambuc 
29311be35a1SLionel Sambuc 	if (isnan(expf(x)) == 0)
29411be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expf(NaN) != NaN");
29511be35a1SLionel Sambuc }
29611be35a1SLionel Sambuc 
29711be35a1SLionel Sambuc ATF_TC(expf_inf_neg);
ATF_TC_HEAD(expf_inf_neg,tc)29811be35a1SLionel Sambuc ATF_TC_HEAD(expf_inf_neg, tc)
29911be35a1SLionel Sambuc {
30011be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expf(-Inf) == +0.0");
30111be35a1SLionel Sambuc }
30211be35a1SLionel Sambuc 
ATF_TC_BODY(expf_inf_neg,tc)30311be35a1SLionel Sambuc ATF_TC_BODY(expf_inf_neg, tc)
30411be35a1SLionel Sambuc {
30511be35a1SLionel Sambuc 	const float x = -1.0L / 0.0L;
30611be35a1SLionel Sambuc 	float y = expf(x);
30711be35a1SLionel Sambuc 
30811be35a1SLionel Sambuc 	if (fabsf(y) > 0.0 || signbit(y) != 0)
30911be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expf(-Inf) != +0.0");
31011be35a1SLionel Sambuc }
31111be35a1SLionel Sambuc 
31211be35a1SLionel Sambuc ATF_TC(expf_inf_pos);
ATF_TC_HEAD(expf_inf_pos,tc)31311be35a1SLionel Sambuc ATF_TC_HEAD(expf_inf_pos, tc)
31411be35a1SLionel Sambuc {
31511be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expf(+Inf) == +Inf");
31611be35a1SLionel Sambuc }
31711be35a1SLionel Sambuc 
ATF_TC_BODY(expf_inf_pos,tc)31811be35a1SLionel Sambuc ATF_TC_BODY(expf_inf_pos, tc)
31911be35a1SLionel Sambuc {
32011be35a1SLionel Sambuc 	const float x = 1.0L / 0.0L;
32111be35a1SLionel Sambuc 	float y = expf(x);
32211be35a1SLionel Sambuc 
32311be35a1SLionel Sambuc 	if (isinf(y) == 0 || signbit(y) != 0)
32411be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expf(+Inf) != +Inf");
32511be35a1SLionel Sambuc }
32611be35a1SLionel Sambuc 
32711be35a1SLionel Sambuc ATF_TC(expf_product);
ATF_TC_HEAD(expf_product,tc)32811be35a1SLionel Sambuc ATF_TC_HEAD(expf_product, tc)
32911be35a1SLionel Sambuc {
33011be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test some selected expf(x)");
33111be35a1SLionel Sambuc }
33211be35a1SLionel Sambuc 
ATF_TC_BODY(expf_product,tc)33311be35a1SLionel Sambuc ATF_TC_BODY(expf_product, tc)
33411be35a1SLionel Sambuc {
33511be35a1SLionel Sambuc 	float eps;
33611be35a1SLionel Sambuc 	float x;
33711be35a1SLionel Sambuc 	float y;
33811be35a1SLionel Sambuc 	size_t i;
33911be35a1SLionel Sambuc 
34011be35a1SLionel Sambuc 	for (i = 0; i < __arraycount(exp_values); i++) {
34111be35a1SLionel Sambuc 		x = exp_values[i].x;
34211be35a1SLionel Sambuc 		y = exp_values[i].y;
34311be35a1SLionel Sambuc 		eps = 1e-6 * exp_values[i].e;
34411be35a1SLionel Sambuc 
34511be35a1SLionel Sambuc 		if (fabsf(expf(x) - y) > eps)
34611be35a1SLionel Sambuc 			atf_tc_fail_nonfatal("expf(%0.01f) != %18.18e", x, y);
34711be35a1SLionel Sambuc 	}
34811be35a1SLionel Sambuc }
34911be35a1SLionel Sambuc 
35011be35a1SLionel Sambuc ATF_TC(expf_zero_neg);
ATF_TC_HEAD(expf_zero_neg,tc)35111be35a1SLionel Sambuc ATF_TC_HEAD(expf_zero_neg, tc)
35211be35a1SLionel Sambuc {
35311be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expf(-0.0) == 1.0");
35411be35a1SLionel Sambuc }
35511be35a1SLionel Sambuc 
ATF_TC_BODY(expf_zero_neg,tc)35611be35a1SLionel Sambuc ATF_TC_BODY(expf_zero_neg, tc)
35711be35a1SLionel Sambuc {
35811be35a1SLionel Sambuc 	const float x = -0.0L;
35911be35a1SLionel Sambuc 
360*0a6a1f1dSLionel Sambuc 	if (fabsf(expf(x) - 1.0f) > 0.0)
36111be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expf(-0.0) != 1.0");
36211be35a1SLionel Sambuc }
36311be35a1SLionel Sambuc 
36411be35a1SLionel Sambuc ATF_TC(expf_zero_pos);
ATF_TC_HEAD(expf_zero_pos,tc)36511be35a1SLionel Sambuc ATF_TC_HEAD(expf_zero_pos, tc)
36611be35a1SLionel Sambuc {
36711be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expf(+0.0) == 1.0");
36811be35a1SLionel Sambuc }
36911be35a1SLionel Sambuc 
ATF_TC_BODY(expf_zero_pos,tc)37011be35a1SLionel Sambuc ATF_TC_BODY(expf_zero_pos, tc)
37111be35a1SLionel Sambuc {
37211be35a1SLionel Sambuc 	const float x = 0.0L;
37311be35a1SLionel Sambuc 
374*0a6a1f1dSLionel Sambuc 	if (fabsf(expf(x) - 1.0f) > 0.0)
37511be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expf(+0.0) != 1.0");
37611be35a1SLionel Sambuc }
37711be35a1SLionel Sambuc 
37811be35a1SLionel Sambuc /*
37911be35a1SLionel Sambuc  * expm1(3)
38011be35a1SLionel Sambuc  */
38111be35a1SLionel Sambuc ATF_TC(expm1_nan);
ATF_TC_HEAD(expm1_nan,tc)38211be35a1SLionel Sambuc ATF_TC_HEAD(expm1_nan, tc)
38311be35a1SLionel Sambuc {
38411be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1(NaN) == NaN");
38511be35a1SLionel Sambuc }
38611be35a1SLionel Sambuc 
ATF_TC_BODY(expm1_nan,tc)38711be35a1SLionel Sambuc ATF_TC_BODY(expm1_nan, tc)
38811be35a1SLionel Sambuc {
38911be35a1SLionel Sambuc 	const double x = 0.0L / 0.0L;
39011be35a1SLionel Sambuc 
39111be35a1SLionel Sambuc 	if (isnan(expm1(x)) == 0)
39211be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1(NaN) != NaN");
39311be35a1SLionel Sambuc }
39411be35a1SLionel Sambuc 
39511be35a1SLionel Sambuc ATF_TC(expm1_inf_neg);
ATF_TC_HEAD(expm1_inf_neg,tc)39611be35a1SLionel Sambuc ATF_TC_HEAD(expm1_inf_neg, tc)
39711be35a1SLionel Sambuc {
39811be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1(-Inf) == -1");
39911be35a1SLionel Sambuc }
40011be35a1SLionel Sambuc 
ATF_TC_BODY(expm1_inf_neg,tc)40111be35a1SLionel Sambuc ATF_TC_BODY(expm1_inf_neg, tc)
40211be35a1SLionel Sambuc {
40311be35a1SLionel Sambuc 	const double x = -1.0L / 0.0L;
40411be35a1SLionel Sambuc 
40511be35a1SLionel Sambuc 	if (expm1(x) != -1.0)
40611be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1(-Inf) != -1.0");
40711be35a1SLionel Sambuc }
40811be35a1SLionel Sambuc 
40911be35a1SLionel Sambuc ATF_TC(expm1_inf_pos);
ATF_TC_HEAD(expm1_inf_pos,tc)41011be35a1SLionel Sambuc ATF_TC_HEAD(expm1_inf_pos, tc)
41111be35a1SLionel Sambuc {
41211be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1(+Inf) == +Inf");
41311be35a1SLionel Sambuc }
41411be35a1SLionel Sambuc 
ATF_TC_BODY(expm1_inf_pos,tc)41511be35a1SLionel Sambuc ATF_TC_BODY(expm1_inf_pos, tc)
41611be35a1SLionel Sambuc {
41711be35a1SLionel Sambuc 	const double x = 1.0L / 0.0L;
41811be35a1SLionel Sambuc 	double y = expm1(x);
41911be35a1SLionel Sambuc 
42011be35a1SLionel Sambuc 	if (isinf(y) == 0 || signbit(y) != 0)
42111be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1(+Inf) != +Inf");
42211be35a1SLionel Sambuc }
42311be35a1SLionel Sambuc 
42411be35a1SLionel Sambuc ATF_TC(expm1_zero_neg);
ATF_TC_HEAD(expm1_zero_neg,tc)42511be35a1SLionel Sambuc ATF_TC_HEAD(expm1_zero_neg, tc)
42611be35a1SLionel Sambuc {
42711be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1(-0.0) == -0.0");
42811be35a1SLionel Sambuc }
42911be35a1SLionel Sambuc 
ATF_TC_BODY(expm1_zero_neg,tc)43011be35a1SLionel Sambuc ATF_TC_BODY(expm1_zero_neg, tc)
43111be35a1SLionel Sambuc {
43211be35a1SLionel Sambuc 	const double x = -0.0L;
43311be35a1SLionel Sambuc 	double y = expm1(x);
43411be35a1SLionel Sambuc 
43511be35a1SLionel Sambuc 	if (fabs(y) > 0.0 || signbit(y) == 0)
43611be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1(-0.0) != -0.0");
43711be35a1SLionel Sambuc }
43811be35a1SLionel Sambuc 
43911be35a1SLionel Sambuc ATF_TC(expm1_zero_pos);
ATF_TC_HEAD(expm1_zero_pos,tc)44011be35a1SLionel Sambuc ATF_TC_HEAD(expm1_zero_pos, tc)
44111be35a1SLionel Sambuc {
44211be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1(+0.0) == 1.0");
44311be35a1SLionel Sambuc }
44411be35a1SLionel Sambuc 
ATF_TC_BODY(expm1_zero_pos,tc)44511be35a1SLionel Sambuc ATF_TC_BODY(expm1_zero_pos, tc)
44611be35a1SLionel Sambuc {
44711be35a1SLionel Sambuc 	const double x = 0.0L;
44811be35a1SLionel Sambuc 	double y = expm1(x);
44911be35a1SLionel Sambuc 
45011be35a1SLionel Sambuc 	if (fabs(y) > 0.0 || signbit(y) != 0)
45111be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1(+0.0) != +0.0");
45211be35a1SLionel Sambuc }
45311be35a1SLionel Sambuc 
45411be35a1SLionel Sambuc /*
45511be35a1SLionel Sambuc  * expm1f(3)
45611be35a1SLionel Sambuc  */
45711be35a1SLionel Sambuc ATF_TC(expm1f_nan);
ATF_TC_HEAD(expm1f_nan,tc)45811be35a1SLionel Sambuc ATF_TC_HEAD(expm1f_nan, tc)
45911be35a1SLionel Sambuc {
46011be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1f(NaN) == NaN");
46111be35a1SLionel Sambuc }
46211be35a1SLionel Sambuc 
ATF_TC_BODY(expm1f_nan,tc)46311be35a1SLionel Sambuc ATF_TC_BODY(expm1f_nan, tc)
46411be35a1SLionel Sambuc {
46511be35a1SLionel Sambuc 	const float x = 0.0L / 0.0L;
46611be35a1SLionel Sambuc 
46711be35a1SLionel Sambuc 	if (isnan(expm1f(x)) == 0)
46811be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1f(NaN) != NaN");
46911be35a1SLionel Sambuc }
47011be35a1SLionel Sambuc 
47111be35a1SLionel Sambuc ATF_TC(expm1f_inf_neg);
ATF_TC_HEAD(expm1f_inf_neg,tc)47211be35a1SLionel Sambuc ATF_TC_HEAD(expm1f_inf_neg, tc)
47311be35a1SLionel Sambuc {
47411be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1f(-Inf) == -1");
47511be35a1SLionel Sambuc }
47611be35a1SLionel Sambuc 
ATF_TC_BODY(expm1f_inf_neg,tc)47711be35a1SLionel Sambuc ATF_TC_BODY(expm1f_inf_neg, tc)
47811be35a1SLionel Sambuc {
47911be35a1SLionel Sambuc 	const float x = -1.0L / 0.0L;
48011be35a1SLionel Sambuc 
48111be35a1SLionel Sambuc 	if (expm1f(x) != -1.0)
48211be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1f(-Inf) != -1.0");
48311be35a1SLionel Sambuc }
48411be35a1SLionel Sambuc 
48511be35a1SLionel Sambuc ATF_TC(expm1f_inf_pos);
ATF_TC_HEAD(expm1f_inf_pos,tc)48611be35a1SLionel Sambuc ATF_TC_HEAD(expm1f_inf_pos, tc)
48711be35a1SLionel Sambuc {
48811be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1f(+Inf) == +Inf");
48911be35a1SLionel Sambuc }
49011be35a1SLionel Sambuc 
ATF_TC_BODY(expm1f_inf_pos,tc)49111be35a1SLionel Sambuc ATF_TC_BODY(expm1f_inf_pos, tc)
49211be35a1SLionel Sambuc {
49311be35a1SLionel Sambuc 	const float x = 1.0L / 0.0L;
49411be35a1SLionel Sambuc 	float y = expm1f(x);
49511be35a1SLionel Sambuc 
49611be35a1SLionel Sambuc 	if (isinf(y) == 0 || signbit(y) != 0)
49711be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1f(+Inf) != +Inf");
49811be35a1SLionel Sambuc }
49911be35a1SLionel Sambuc 
50011be35a1SLionel Sambuc ATF_TC(expm1f_zero_neg);
ATF_TC_HEAD(expm1f_zero_neg,tc)50111be35a1SLionel Sambuc ATF_TC_HEAD(expm1f_zero_neg, tc)
50211be35a1SLionel Sambuc {
50311be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1f(-0.0) == -0.0");
50411be35a1SLionel Sambuc }
50511be35a1SLionel Sambuc 
ATF_TC_BODY(expm1f_zero_neg,tc)50611be35a1SLionel Sambuc ATF_TC_BODY(expm1f_zero_neg, tc)
50711be35a1SLionel Sambuc {
50811be35a1SLionel Sambuc 	const float x = -0.0L;
50911be35a1SLionel Sambuc 	float y = expm1f(x);
51011be35a1SLionel Sambuc 
51111be35a1SLionel Sambuc 	if (fabsf(y) > 0.0 || signbit(y) == 0)
51211be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1f(-0.0) != -0.0");
51311be35a1SLionel Sambuc }
51411be35a1SLionel Sambuc 
51511be35a1SLionel Sambuc ATF_TC(expm1f_zero_pos);
ATF_TC_HEAD(expm1f_zero_pos,tc)51611be35a1SLionel Sambuc ATF_TC_HEAD(expm1f_zero_pos, tc)
51711be35a1SLionel Sambuc {
51811be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Test expm1f(+0.0) == 1.0");
51911be35a1SLionel Sambuc }
52011be35a1SLionel Sambuc 
ATF_TC_BODY(expm1f_zero_pos,tc)52111be35a1SLionel Sambuc ATF_TC_BODY(expm1f_zero_pos, tc)
52211be35a1SLionel Sambuc {
52311be35a1SLionel Sambuc 	const float x = 0.0L;
52411be35a1SLionel Sambuc 	float y = expm1f(x);
52511be35a1SLionel Sambuc 
52611be35a1SLionel Sambuc 	if (fabsf(y) > 0.0 || signbit(y) != 0)
52711be35a1SLionel Sambuc 		atf_tc_fail_nonfatal("expm1f(+0.0) != +0.0");
52811be35a1SLionel Sambuc }
52911be35a1SLionel Sambuc 
ATF_TP_ADD_TCS(tp)53011be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp)
53111be35a1SLionel Sambuc {
53211be35a1SLionel Sambuc 
533*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, exp2_is_nan);
534*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, exp2_is_plus_zero);
535*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, exp2_values);
536*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, exp2_powers);
53711be35a1SLionel Sambuc 
53811be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, exp_nan);
53911be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, exp_inf_neg);
54011be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, exp_inf_pos);
54111be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, exp_product);
54211be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, exp_zero_neg);
54311be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, exp_zero_pos);
54411be35a1SLionel Sambuc 
54511be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expf_nan);
54611be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expf_inf_neg);
54711be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expf_inf_pos);
54811be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expf_product);
54911be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expf_zero_neg);
55011be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expf_zero_pos);
55111be35a1SLionel Sambuc 
55211be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1_nan);
55311be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1_inf_neg);
55411be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1_inf_pos);
55511be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1_zero_neg);
55611be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1_zero_pos);
55711be35a1SLionel Sambuc 
55811be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1f_nan);
55911be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1f_inf_neg);
56011be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1f_inf_pos);
56111be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1f_zero_neg);
56211be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, expm1f_zero_pos);
56311be35a1SLionel Sambuc 
56411be35a1SLionel Sambuc 	return atf_no_error();
56511be35a1SLionel Sambuc }
566