t_exp.c revision 272343
1272343Sngie/* $NetBSD: t_exp.c,v 1.7 2014/03/17 11:08:11 martin Exp $ */
2272343Sngie
3272343Sngie/*-
4272343Sngie * Copyright (c) 2011 The NetBSD Foundation, Inc.
5272343Sngie * All rights reserved.
6272343Sngie *
7272343Sngie * This code is derived from software contributed to The NetBSD Foundation
8272343Sngie * by Jukka Ruohonen.
9272343Sngie *
10272343Sngie * Redistribution and use in source and binary forms, with or without
11272343Sngie * modification, are permitted provided that the following conditions
12272343Sngie * are met:
13272343Sngie * 1. Redistributions of source code must retain the above copyright
14272343Sngie *    notice, this list of conditions and the following disclaimer.
15272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
16272343Sngie *    notice, this list of conditions and the following disclaimer in the
17272343Sngie *    documentation and/or other materials provided with the distribution.
18272343Sngie *
19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22272343Sngie * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29272343Sngie * POSSIBILITY OF SUCH DAMAGE.
30272343Sngie */
31272343Sngie
32272343Sngie#include <atf-c.h>
33272343Sngie#include <math.h>
34272343Sngie#include "t_libm.h"
35272343Sngie
36272343Sngie/* y = exp(x) */
37272343Sngiestatic const struct {
38272343Sngie	double x;
39272343Sngie	double y;
40272343Sngie	double e;
41272343Sngie} exp_values[] = {
42272343Sngie	{  -10, 0.4539992976248485e-4, 1e-4, },
43272343Sngie	{   -5, 0.6737946999085467e-2, 1e-2, },
44272343Sngie	{   -1, 0.3678794411714423,    1e-1, },
45272343Sngie	{ -0.1, 0.9048374180359595,    1e-1, },
46272343Sngie	{    0, 1.0000000000000000,    1,    },
47272343Sngie	{  0.1, 1.1051709180756477,    1,    },
48272343Sngie	{    1, 2.7182818284590452,    1,    },
49272343Sngie	{    5, 148.41315910257660,    1e2, },
50272343Sngie	{   10, 22026.465794806718,    1e4, },
51272343Sngie};
52272343Sngie
53272343Sngie/*
54272343Sngie * exp2/exp2f(3)
55272343Sngie */
56272343SngieATF_LIBM_TEST(exp2_is_nan, "Test exp2(x) == NaN")
57272343Sngie{
58272343Sngie#ifdef T_LIBM_NAN
59272343Sngie	T_LIBM_CHECK_NAN(0, exp2, T_LIBM_NAN);
60272343Sngie	T_LIBM_CHECK_NAN(0, exp2f, T_LIBM_NAN);
61272343Sngie#else
62272343Sngie	atf_tc_skip("no NaN on this machine");
63272343Sngie#endif
64272343Sngie}
65272343Sngie
66272343SngieATF_LIBM_TEST(exp2_is_plus_zero, "Test exp2(x) == +0.0")
67272343Sngie{
68272343Sngie#ifdef T_LIBM_MINUS_INF
69272343Sngie	T_LIBM_CHECK_PLUS_ZERO(0, exp2, T_LIBM_MINUS_INF);
70272343Sngie	T_LIBM_CHECK_PLUS_ZERO(0, exp2f, T_LIBM_MINUS_INF);
71272343Sngie#else
72272343Sngie	atf_tc_skip("no +/-Inf on this machine");
73272343Sngie#endif
74272343Sngie}
75272343Sngie
76272343SngieATF_LIBM_TEST(exp2_powers, "Test exp2(x) is correct for some integer x")
77272343Sngie{
78272343Sngie	static const struct {
79272343Sngie		double	x;
80272343Sngie		double	d_y;
81272343Sngie		double	f_y;
82272343Sngie	} v[] = {
83272343Sngie	    { +0.0,	1.0,	1.0 },
84272343Sngie	    { -0.0,	1.0,	1.0 },
85272343Sngie	    {    1,	0x1p1,	0x1p1 },
86272343Sngie	    {    2,	0x1p2,	0x1p2 },
87272343Sngie	    {  100,	0x1p100,	0x1p100 },
88272343Sngie	    {  125,	0x1p125,	0x1p125 },
89272343Sngie	    {  126,	0x1p126,	0x1p126 },
90272343Sngie#if __DBL_MAX_EXP__ > 129
91272343Sngie	    {  127,	0x1p127,	0x1p127 },
92272343Sngie#endif
93272343Sngie#ifdef T_LIBM_PLUS_INF
94272343Sngie	    {  128,	0x1p128,	T_LIBM_PLUS_INF },
95272343Sngie	    {  129,	0x1p129,	T_LIBM_PLUS_INF },
96272343Sngie	    { 1000,	0x1p1000,	T_LIBM_PLUS_INF },
97272343Sngie	    { 1020,	0x1p1020,	T_LIBM_PLUS_INF },
98272343Sngie	    { 1023,	0x1p1023,	T_LIBM_PLUS_INF },
99272343Sngie	    { 1024,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
100272343Sngie	    { 1030,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
101272343Sngie	    { 1050,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
102272343Sngie	    { 2000,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
103272343Sngie	    { 16383,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
104272343Sngie	    { 16384,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
105272343Sngie	    { 16385,	T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF },
106272343Sngie#endif
107272343Sngie	    {   -1,	0x1p-1,	0x1p-1 },
108272343Sngie	    {   -2,	0x1p-2,	0x1p-2 },
109272343Sngie	    { -100,	0x1p-100,	0x1p-100 },
110272343Sngie	    { -127,	0x1p-127,	0x1p-127 },
111272343Sngie	    { -128,	0x1p-128,	0x1p-128 },
112272343Sngie#if __LDBL_MIN_EXP__ < -129
113272343Sngie	    { -300,	0x1p-300,	0.0},
114272343Sngie	    { -400,	0x1p-400,	0.0},
115272343Sngie	    {-1000,	0x1p-1000,	0.0},
116272343Sngie	    {-1022,	0x1p-1022,	0.0},
117272343Sngie	    /* These should be denormal numbers */
118272343Sngie	    {-1023,	0x1p-1023,	0.0},
119272343Sngie	    {-1024,	0x1p-1024,	0.0},
120272343Sngie	    {-1040,	0x1p-1040,	0.0},
121272343Sngie	    {-1060,	0x1p-1060,	0.0},
122272343Sngie	    /* This is the smallest result gcc will allow */
123272343Sngie	    {-1074,	0x1p-1074,	0.0},
124272343Sngie#endif
125272343Sngie	    {-1075,	0x0,	0.0},
126272343Sngie	    {-1080,	0x0,	0.0},
127272343Sngie	    {-2000,	0x0,	0.0},
128272343Sngie	    {-16382,	0x0,	0.0},
129272343Sngie	    {-16383,	0x0,	0.0},
130272343Sngie	    {-16384,	0x0,	0.0},
131272343Sngie	};
132272343Sngie	unsigned int i;
133272343Sngie
134272343Sngie	for (i = 0; i < __arraycount(v); i++) {
135272343Sngie		T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, 0.0);
136272343Sngie		T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, 0.0);
137272343Sngie	}
138272343Sngie}
139272343Sngie
140272343SngieATF_LIBM_TEST(exp2_values, "Test exp2(x) is correct for some x")
141272343Sngie{
142272343Sngie	static const struct {
143272343Sngie		double	x;
144272343Sngie		double	y;
145272343Sngie		double	d_eps;
146272343Sngie		double	f_eps;
147272343Sngie	} v[] = {
148272343Sngie#if __DBL_MAX_EXP__ > 128
149272343Sngie	    /* The largest double constant */
150272343Sngie	    { 0x1.fffffffffffffp9,	0x1.ffffffffffd3ap1023,
151272343Sngie		0x1p969,	0.0 },
152272343Sngie	    /* The largest float constant */
153272343Sngie	    { 0x1.fffffep6,	0x1.ffff4ep+127,	6e30,	0.0 },
154272343Sngie#endif
155272343Sngie#ifdef T_LIBM_PLUS_INF
156272343Sngie	    { T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF,	0.0,	0.0 },
157272343Sngie#endif
158272343Sngie
159272343Sngie	    /* The few values from the old tests */
160272343Sngie	    /* Results from i386/amd64, d_eps needed on i386 */
161272343Sngie	    {  1.1,	0x1.125fbee250664p+1,	0x1p-52,	0x1.8p-22 },
162272343Sngie	    {  2.2,	0x1.2611186bae675p+2,	0x1p-51,	0x1.8p-21 },
163272343Sngie	    {  3.3,	0x1.3b2c47bff8328p+3,	0x1p-50,	0x1.8p-20 },
164272343Sngie	    {  4.4,	0x1.51cb453b9536ep+4,	0x1p-49,	0x1.8p-19 },
165272343Sngie	    {  5.5,	0x1.6a09e667f3bcdp+5,	0x1p-48,	0x1.8p-18 },
166272343Sngie	    {  6.6,	0x1.8406003b2ae5bp+6,	0x1p-47,	0x1.8p-17 },
167272343Sngie	    /*
168272343Sngie	     * These two currently fail for 'float'.
169272343Sngie	     * 8.8 is definitely out by more than it should be.
170272343Sngie	     */
171272343Sngie	    {  7.7,	0x1.9fdf8bcce533ep+7,	0x1p-46,	0x1.8p-16 },
172272343Sngie	    {  8.8,	0x1.bdb8cdadbe124p+8,	0x1p-45,	0x1.8p-15 },
173272343Sngie	};
174272343Sngie	unsigned int i;
175272343Sngie
176272343Sngie	for (i = 0; i < __arraycount(v); i++) {
177272343Sngie		T_LIBM_CHECK(i, exp2, v[i].x, v[i].y, v[i].d_eps);
178272343Sngie		if (i > 1)
179272343Sngie			T_LIBM_CHECK(i, exp2f, v[i].x, v[i].y, v[i].f_eps);
180272343Sngie	}
181272343Sngie}
182272343Sngie
183272343Sngie
184272343Sngie/*
185272343Sngie * exp(3)
186272343Sngie */
187272343SngieATF_TC(exp_nan);
188272343SngieATF_TC_HEAD(exp_nan, tc)
189272343Sngie{
190272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(NaN) == NaN");
191272343Sngie}
192272343Sngie
193272343SngieATF_TC_BODY(exp_nan, tc)
194272343Sngie{
195272343Sngie	const double x = 0.0L / 0.0L;
196272343Sngie
197272343Sngie	if (isnan(exp(x)) == 0)
198272343Sngie		atf_tc_fail_nonfatal("exp(NaN) != NaN");
199272343Sngie}
200272343Sngie
201272343SngieATF_TC(exp_inf_neg);
202272343SngieATF_TC_HEAD(exp_inf_neg, tc)
203272343Sngie{
204272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(-Inf) == +0.0");
205272343Sngie}
206272343Sngie
207272343SngieATF_TC_BODY(exp_inf_neg, tc)
208272343Sngie{
209272343Sngie	const double x = -1.0L / 0.0L;
210272343Sngie	double y = exp(x);
211272343Sngie
212272343Sngie	if (fabs(y) > 0.0 || signbit(y) != 0)
213272343Sngie		atf_tc_fail_nonfatal("exp(-Inf) != +0.0");
214272343Sngie}
215272343Sngie
216272343SngieATF_TC(exp_inf_pos);
217272343SngieATF_TC_HEAD(exp_inf_pos, tc)
218272343Sngie{
219272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(+Inf) == +Inf");
220272343Sngie}
221272343Sngie
222272343SngieATF_TC_BODY(exp_inf_pos, tc)
223272343Sngie{
224272343Sngie	const double x = 1.0L / 0.0L;
225272343Sngie	double y = exp(x);
226272343Sngie
227272343Sngie	if (isinf(y) == 0 || signbit(y) != 0)
228272343Sngie		atf_tc_fail_nonfatal("exp(+Inf) != +Inf");
229272343Sngie}
230272343Sngie
231272343SngieATF_TC(exp_product);
232272343SngieATF_TC_HEAD(exp_product, tc)
233272343Sngie{
234272343Sngie	atf_tc_set_md_var(tc, "descr", "Test some selected exp(x)");
235272343Sngie}
236272343Sngie
237272343SngieATF_TC_BODY(exp_product, tc)
238272343Sngie{
239272343Sngie	double eps;
240272343Sngie	double x;
241272343Sngie	double y;
242272343Sngie	size_t i;
243272343Sngie
244272343Sngie	for (i = 0; i < __arraycount(exp_values); i++) {
245272343Sngie		x = exp_values[i].x;
246272343Sngie		y = exp_values[i].y;
247272343Sngie		eps = 1e-15 * exp_values[i].e;
248272343Sngie
249272343Sngie		if (fabs(exp(x) - y) > eps)
250272343Sngie			atf_tc_fail_nonfatal("exp(%0.01f) != %18.18e", x, y);
251272343Sngie	}
252272343Sngie}
253272343Sngie
254272343SngieATF_TC(exp_zero_neg);
255272343SngieATF_TC_HEAD(exp_zero_neg, tc)
256272343Sngie{
257272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(-0.0) == 1.0");
258272343Sngie}
259272343Sngie
260272343SngieATF_TC_BODY(exp_zero_neg, tc)
261272343Sngie{
262272343Sngie	const double x = -0.0L;
263272343Sngie
264272343Sngie	if (fabs(exp(x) - 1.0) > 0.0)
265272343Sngie		atf_tc_fail_nonfatal("exp(-0.0) != 1.0");
266272343Sngie}
267272343Sngie
268272343SngieATF_TC(exp_zero_pos);
269272343SngieATF_TC_HEAD(exp_zero_pos, tc)
270272343Sngie{
271272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(+0.0) == 1.0");
272272343Sngie}
273272343Sngie
274272343SngieATF_TC_BODY(exp_zero_pos, tc)
275272343Sngie{
276272343Sngie	const double x = 0.0L;
277272343Sngie
278272343Sngie	if (fabs(exp(x) - 1.0) > 0.0)
279272343Sngie		atf_tc_fail_nonfatal("exp(+0.0) != 1.0");
280272343Sngie}
281272343Sngie
282272343Sngie/*
283272343Sngie * expf(3)
284272343Sngie */
285272343SngieATF_TC(expf_nan);
286272343SngieATF_TC_HEAD(expf_nan, tc)
287272343Sngie{
288272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(NaN) == NaN");
289272343Sngie}
290272343Sngie
291272343SngieATF_TC_BODY(expf_nan, tc)
292272343Sngie{
293272343Sngie	const float x = 0.0L / 0.0L;
294272343Sngie
295272343Sngie	if (isnan(expf(x)) == 0)
296272343Sngie		atf_tc_fail_nonfatal("expf(NaN) != NaN");
297272343Sngie}
298272343Sngie
299272343SngieATF_TC(expf_inf_neg);
300272343SngieATF_TC_HEAD(expf_inf_neg, tc)
301272343Sngie{
302272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(-Inf) == +0.0");
303272343Sngie}
304272343Sngie
305272343SngieATF_TC_BODY(expf_inf_neg, tc)
306272343Sngie{
307272343Sngie	const float x = -1.0L / 0.0L;
308272343Sngie	float y = expf(x);
309272343Sngie
310272343Sngie	if (fabsf(y) > 0.0 || signbit(y) != 0)
311272343Sngie		atf_tc_fail_nonfatal("expf(-Inf) != +0.0");
312272343Sngie}
313272343Sngie
314272343SngieATF_TC(expf_inf_pos);
315272343SngieATF_TC_HEAD(expf_inf_pos, tc)
316272343Sngie{
317272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(+Inf) == +Inf");
318272343Sngie}
319272343Sngie
320272343SngieATF_TC_BODY(expf_inf_pos, tc)
321272343Sngie{
322272343Sngie	const float x = 1.0L / 0.0L;
323272343Sngie	float y = expf(x);
324272343Sngie
325272343Sngie	if (isinf(y) == 0 || signbit(y) != 0)
326272343Sngie		atf_tc_fail_nonfatal("expf(+Inf) != +Inf");
327272343Sngie}
328272343Sngie
329272343SngieATF_TC(expf_product);
330272343SngieATF_TC_HEAD(expf_product, tc)
331272343Sngie{
332272343Sngie	atf_tc_set_md_var(tc, "descr", "Test some selected expf(x)");
333272343Sngie}
334272343Sngie
335272343SngieATF_TC_BODY(expf_product, tc)
336272343Sngie{
337272343Sngie	float eps;
338272343Sngie	float x;
339272343Sngie	float y;
340272343Sngie	size_t i;
341272343Sngie
342272343Sngie	for (i = 0; i < __arraycount(exp_values); i++) {
343272343Sngie		x = exp_values[i].x;
344272343Sngie		y = exp_values[i].y;
345272343Sngie		eps = 1e-6 * exp_values[i].e;
346272343Sngie
347272343Sngie		if (fabsf(expf(x) - y) > eps)
348272343Sngie			atf_tc_fail_nonfatal("expf(%0.01f) != %18.18e", x, y);
349272343Sngie	}
350272343Sngie}
351272343Sngie
352272343SngieATF_TC(expf_zero_neg);
353272343SngieATF_TC_HEAD(expf_zero_neg, tc)
354272343Sngie{
355272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(-0.0) == 1.0");
356272343Sngie}
357272343Sngie
358272343SngieATF_TC_BODY(expf_zero_neg, tc)
359272343Sngie{
360272343Sngie	const float x = -0.0L;
361272343Sngie
362272343Sngie	if (fabsf(expf(x) - 1.0f) > 0.0)
363272343Sngie		atf_tc_fail_nonfatal("expf(-0.0) != 1.0");
364272343Sngie}
365272343Sngie
366272343SngieATF_TC(expf_zero_pos);
367272343SngieATF_TC_HEAD(expf_zero_pos, tc)
368272343Sngie{
369272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(+0.0) == 1.0");
370272343Sngie}
371272343Sngie
372272343SngieATF_TC_BODY(expf_zero_pos, tc)
373272343Sngie{
374272343Sngie	const float x = 0.0L;
375272343Sngie
376272343Sngie	if (fabsf(expf(x) - 1.0f) > 0.0)
377272343Sngie		atf_tc_fail_nonfatal("expf(+0.0) != 1.0");
378272343Sngie}
379272343Sngie
380272343Sngie/*
381272343Sngie * expm1(3)
382272343Sngie */
383272343SngieATF_TC(expm1_nan);
384272343SngieATF_TC_HEAD(expm1_nan, tc)
385272343Sngie{
386272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(NaN) == NaN");
387272343Sngie}
388272343Sngie
389272343SngieATF_TC_BODY(expm1_nan, tc)
390272343Sngie{
391272343Sngie	const double x = 0.0L / 0.0L;
392272343Sngie
393272343Sngie	if (isnan(expm1(x)) == 0)
394272343Sngie		atf_tc_fail_nonfatal("expm1(NaN) != NaN");
395272343Sngie}
396272343Sngie
397272343SngieATF_TC(expm1_inf_neg);
398272343SngieATF_TC_HEAD(expm1_inf_neg, tc)
399272343Sngie{
400272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(-Inf) == -1");
401272343Sngie}
402272343Sngie
403272343SngieATF_TC_BODY(expm1_inf_neg, tc)
404272343Sngie{
405272343Sngie	const double x = -1.0L / 0.0L;
406272343Sngie
407272343Sngie	if (expm1(x) != -1.0)
408272343Sngie		atf_tc_fail_nonfatal("expm1(-Inf) != -1.0");
409272343Sngie}
410272343Sngie
411272343SngieATF_TC(expm1_inf_pos);
412272343SngieATF_TC_HEAD(expm1_inf_pos, tc)
413272343Sngie{
414272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(+Inf) == +Inf");
415272343Sngie}
416272343Sngie
417272343SngieATF_TC_BODY(expm1_inf_pos, tc)
418272343Sngie{
419272343Sngie	const double x = 1.0L / 0.0L;
420272343Sngie	double y = expm1(x);
421272343Sngie
422272343Sngie	if (isinf(y) == 0 || signbit(y) != 0)
423272343Sngie		atf_tc_fail_nonfatal("expm1(+Inf) != +Inf");
424272343Sngie}
425272343Sngie
426272343SngieATF_TC(expm1_zero_neg);
427272343SngieATF_TC_HEAD(expm1_zero_neg, tc)
428272343Sngie{
429272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(-0.0) == -0.0");
430272343Sngie}
431272343Sngie
432272343SngieATF_TC_BODY(expm1_zero_neg, tc)
433272343Sngie{
434272343Sngie	const double x = -0.0L;
435272343Sngie	double y = expm1(x);
436272343Sngie
437272343Sngie	if (fabs(y) > 0.0 || signbit(y) == 0)
438272343Sngie		atf_tc_fail_nonfatal("expm1(-0.0) != -0.0");
439272343Sngie}
440272343Sngie
441272343SngieATF_TC(expm1_zero_pos);
442272343SngieATF_TC_HEAD(expm1_zero_pos, tc)
443272343Sngie{
444272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(+0.0) == 1.0");
445272343Sngie}
446272343Sngie
447272343SngieATF_TC_BODY(expm1_zero_pos, tc)
448272343Sngie{
449272343Sngie	const double x = 0.0L;
450272343Sngie	double y = expm1(x);
451272343Sngie
452272343Sngie	if (fabs(y) > 0.0 || signbit(y) != 0)
453272343Sngie		atf_tc_fail_nonfatal("expm1(+0.0) != +0.0");
454272343Sngie}
455272343Sngie
456272343Sngie/*
457272343Sngie * expm1f(3)
458272343Sngie */
459272343SngieATF_TC(expm1f_nan);
460272343SngieATF_TC_HEAD(expm1f_nan, tc)
461272343Sngie{
462272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(NaN) == NaN");
463272343Sngie}
464272343Sngie
465272343SngieATF_TC_BODY(expm1f_nan, tc)
466272343Sngie{
467272343Sngie	const float x = 0.0L / 0.0L;
468272343Sngie
469272343Sngie	if (isnan(expm1f(x)) == 0)
470272343Sngie		atf_tc_fail_nonfatal("expm1f(NaN) != NaN");
471272343Sngie}
472272343Sngie
473272343SngieATF_TC(expm1f_inf_neg);
474272343SngieATF_TC_HEAD(expm1f_inf_neg, tc)
475272343Sngie{
476272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(-Inf) == -1");
477272343Sngie}
478272343Sngie
479272343SngieATF_TC_BODY(expm1f_inf_neg, tc)
480272343Sngie{
481272343Sngie	const float x = -1.0L / 0.0L;
482272343Sngie
483272343Sngie	if (expm1f(x) != -1.0)
484272343Sngie		atf_tc_fail_nonfatal("expm1f(-Inf) != -1.0");
485272343Sngie}
486272343Sngie
487272343SngieATF_TC(expm1f_inf_pos);
488272343SngieATF_TC_HEAD(expm1f_inf_pos, tc)
489272343Sngie{
490272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(+Inf) == +Inf");
491272343Sngie}
492272343Sngie
493272343SngieATF_TC_BODY(expm1f_inf_pos, tc)
494272343Sngie{
495272343Sngie	const float x = 1.0L / 0.0L;
496272343Sngie	float y = expm1f(x);
497272343Sngie
498272343Sngie	if (isinf(y) == 0 || signbit(y) != 0)
499272343Sngie		atf_tc_fail_nonfatal("expm1f(+Inf) != +Inf");
500272343Sngie}
501272343Sngie
502272343SngieATF_TC(expm1f_zero_neg);
503272343SngieATF_TC_HEAD(expm1f_zero_neg, tc)
504272343Sngie{
505272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(-0.0) == -0.0");
506272343Sngie}
507272343Sngie
508272343SngieATF_TC_BODY(expm1f_zero_neg, tc)
509272343Sngie{
510272343Sngie	const float x = -0.0L;
511272343Sngie	float y = expm1f(x);
512272343Sngie
513272343Sngie	if (fabsf(y) > 0.0 || signbit(y) == 0)
514272343Sngie		atf_tc_fail_nonfatal("expm1f(-0.0) != -0.0");
515272343Sngie}
516272343Sngie
517272343SngieATF_TC(expm1f_zero_pos);
518272343SngieATF_TC_HEAD(expm1f_zero_pos, tc)
519272343Sngie{
520272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(+0.0) == 1.0");
521272343Sngie}
522272343Sngie
523272343SngieATF_TC_BODY(expm1f_zero_pos, tc)
524272343Sngie{
525272343Sngie	const float x = 0.0L;
526272343Sngie	float y = expm1f(x);
527272343Sngie
528272343Sngie	if (fabsf(y) > 0.0 || signbit(y) != 0)
529272343Sngie		atf_tc_fail_nonfatal("expm1f(+0.0) != +0.0");
530272343Sngie}
531272343Sngie
532272343SngieATF_TP_ADD_TCS(tp)
533272343Sngie{
534272343Sngie
535272343Sngie	ATF_TP_ADD_TC(tp, exp2_is_nan);
536272343Sngie	ATF_TP_ADD_TC(tp, exp2_is_plus_zero);
537272343Sngie	ATF_TP_ADD_TC(tp, exp2_values);
538272343Sngie	ATF_TP_ADD_TC(tp, exp2_powers);
539272343Sngie
540272343Sngie	ATF_TP_ADD_TC(tp, exp_nan);
541272343Sngie	ATF_TP_ADD_TC(tp, exp_inf_neg);
542272343Sngie	ATF_TP_ADD_TC(tp, exp_inf_pos);
543272343Sngie	ATF_TP_ADD_TC(tp, exp_product);
544272343Sngie	ATF_TP_ADD_TC(tp, exp_zero_neg);
545272343Sngie	ATF_TP_ADD_TC(tp, exp_zero_pos);
546272343Sngie
547272343Sngie	ATF_TP_ADD_TC(tp, expf_nan);
548272343Sngie	ATF_TP_ADD_TC(tp, expf_inf_neg);
549272343Sngie	ATF_TP_ADD_TC(tp, expf_inf_pos);
550272343Sngie	ATF_TP_ADD_TC(tp, expf_product);
551272343Sngie	ATF_TP_ADD_TC(tp, expf_zero_neg);
552272343Sngie	ATF_TP_ADD_TC(tp, expf_zero_pos);
553272343Sngie
554272343Sngie	ATF_TP_ADD_TC(tp, expm1_nan);
555272343Sngie	ATF_TP_ADD_TC(tp, expm1_inf_neg);
556272343Sngie	ATF_TP_ADD_TC(tp, expm1_inf_pos);
557272343Sngie	ATF_TP_ADD_TC(tp, expm1_zero_neg);
558272343Sngie	ATF_TP_ADD_TC(tp, expm1_zero_pos);
559272343Sngie
560272343Sngie	ATF_TP_ADD_TC(tp, expm1f_nan);
561272343Sngie	ATF_TP_ADD_TC(tp, expm1f_inf_neg);
562272343Sngie	ATF_TP_ADD_TC(tp, expm1f_inf_pos);
563272343Sngie	ATF_TP_ADD_TC(tp, expm1f_zero_neg);
564272343Sngie	ATF_TP_ADD_TC(tp, expm1f_zero_pos);
565272343Sngie
566272343Sngie	return atf_no_error();
567272343Sngie}
568