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