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
134276478Sngie#if defined(__FreeBSD__) && defined(__i386__)
135276478Sngie	atf_tc_expect_fail("a number of the assertions fail on i386");
136276478Sngie#endif
137276478Sngie
138272343Sngie	for (i = 0; i < __arraycount(v); i++) {
139272343Sngie		T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, 0.0);
140272343Sngie		T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, 0.0);
141272343Sngie	}
142272343Sngie}
143272343Sngie
144272343SngieATF_LIBM_TEST(exp2_values, "Test exp2(x) is correct for some x")
145272343Sngie{
146272343Sngie	static const struct {
147272343Sngie		double	x;
148272343Sngie		double	y;
149272343Sngie		double	d_eps;
150272343Sngie		double	f_eps;
151272343Sngie	} v[] = {
152272343Sngie#if __DBL_MAX_EXP__ > 128
153272343Sngie	    /* The largest double constant */
154272343Sngie	    { 0x1.fffffffffffffp9,	0x1.ffffffffffd3ap1023,
155272343Sngie		0x1p969,	0.0 },
156272343Sngie	    /* The largest float constant */
157272343Sngie	    { 0x1.fffffep6,	0x1.ffff4ep+127,	6e30,	0.0 },
158272343Sngie#endif
159272343Sngie#ifdef T_LIBM_PLUS_INF
160272343Sngie	    { T_LIBM_PLUS_INF,	T_LIBM_PLUS_INF,	0.0,	0.0 },
161272343Sngie#endif
162272343Sngie
163272343Sngie	    /* The few values from the old tests */
164272343Sngie	    /* Results from i386/amd64, d_eps needed on i386 */
165272343Sngie	    {  1.1,	0x1.125fbee250664p+1,	0x1p-52,	0x1.8p-22 },
166272343Sngie	    {  2.2,	0x1.2611186bae675p+2,	0x1p-51,	0x1.8p-21 },
167272343Sngie	    {  3.3,	0x1.3b2c47bff8328p+3,	0x1p-50,	0x1.8p-20 },
168272343Sngie	    {  4.4,	0x1.51cb453b9536ep+4,	0x1p-49,	0x1.8p-19 },
169272343Sngie	    {  5.5,	0x1.6a09e667f3bcdp+5,	0x1p-48,	0x1.8p-18 },
170272343Sngie	    {  6.6,	0x1.8406003b2ae5bp+6,	0x1p-47,	0x1.8p-17 },
171272343Sngie	    /*
172272343Sngie	     * These two currently fail for 'float'.
173272343Sngie	     * 8.8 is definitely out by more than it should be.
174272343Sngie	     */
175272343Sngie	    {  7.7,	0x1.9fdf8bcce533ep+7,	0x1p-46,	0x1.8p-16 },
176272343Sngie	    {  8.8,	0x1.bdb8cdadbe124p+8,	0x1p-45,	0x1.8p-15 },
177272343Sngie	};
178272343Sngie	unsigned int i;
179272343Sngie
180276478Sngie#ifdef __FreeBSD__
181276478Sngie	atf_tc_expect_fail("Some of the cases produce failures on FreeBSD "
182276478Sngie	    "due to the error epsilon being so small");
183276478Sngie#endif
184276478Sngie
185272343Sngie	for (i = 0; i < __arraycount(v); i++) {
186272343Sngie		T_LIBM_CHECK(i, exp2, v[i].x, v[i].y, v[i].d_eps);
187272343Sngie		if (i > 1)
188272343Sngie			T_LIBM_CHECK(i, exp2f, v[i].x, v[i].y, v[i].f_eps);
189272343Sngie	}
190272343Sngie}
191272343Sngie
192272343Sngie
193272343Sngie/*
194272343Sngie * exp(3)
195272343Sngie */
196272343SngieATF_TC(exp_nan);
197272343SngieATF_TC_HEAD(exp_nan, tc)
198272343Sngie{
199272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(NaN) == NaN");
200272343Sngie}
201272343Sngie
202272343SngieATF_TC_BODY(exp_nan, tc)
203272343Sngie{
204272343Sngie	const double x = 0.0L / 0.0L;
205272343Sngie
206272343Sngie	if (isnan(exp(x)) == 0)
207272343Sngie		atf_tc_fail_nonfatal("exp(NaN) != NaN");
208272343Sngie}
209272343Sngie
210272343SngieATF_TC(exp_inf_neg);
211272343SngieATF_TC_HEAD(exp_inf_neg, tc)
212272343Sngie{
213272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(-Inf) == +0.0");
214272343Sngie}
215272343Sngie
216272343SngieATF_TC_BODY(exp_inf_neg, tc)
217272343Sngie{
218272343Sngie	const double x = -1.0L / 0.0L;
219272343Sngie	double y = exp(x);
220272343Sngie
221272343Sngie	if (fabs(y) > 0.0 || signbit(y) != 0)
222272343Sngie		atf_tc_fail_nonfatal("exp(-Inf) != +0.0");
223272343Sngie}
224272343Sngie
225272343SngieATF_TC(exp_inf_pos);
226272343SngieATF_TC_HEAD(exp_inf_pos, tc)
227272343Sngie{
228272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(+Inf) == +Inf");
229272343Sngie}
230272343Sngie
231272343SngieATF_TC_BODY(exp_inf_pos, tc)
232272343Sngie{
233272343Sngie	const double x = 1.0L / 0.0L;
234272343Sngie	double y = exp(x);
235272343Sngie
236272343Sngie	if (isinf(y) == 0 || signbit(y) != 0)
237272343Sngie		atf_tc_fail_nonfatal("exp(+Inf) != +Inf");
238272343Sngie}
239272343Sngie
240272343SngieATF_TC(exp_product);
241272343SngieATF_TC_HEAD(exp_product, tc)
242272343Sngie{
243272343Sngie	atf_tc_set_md_var(tc, "descr", "Test some selected exp(x)");
244272343Sngie}
245272343Sngie
246272343SngieATF_TC_BODY(exp_product, tc)
247272343Sngie{
248272343Sngie	double eps;
249272343Sngie	double x;
250272343Sngie	double y;
251272343Sngie	size_t i;
252272343Sngie
253272343Sngie	for (i = 0; i < __arraycount(exp_values); i++) {
254272343Sngie		x = exp_values[i].x;
255272343Sngie		y = exp_values[i].y;
256272343Sngie		eps = 1e-15 * exp_values[i].e;
257272343Sngie
258272343Sngie		if (fabs(exp(x) - y) > eps)
259272343Sngie			atf_tc_fail_nonfatal("exp(%0.01f) != %18.18e", x, y);
260272343Sngie	}
261272343Sngie}
262272343Sngie
263272343SngieATF_TC(exp_zero_neg);
264272343SngieATF_TC_HEAD(exp_zero_neg, tc)
265272343Sngie{
266272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(-0.0) == 1.0");
267272343Sngie}
268272343Sngie
269272343SngieATF_TC_BODY(exp_zero_neg, tc)
270272343Sngie{
271272343Sngie	const double x = -0.0L;
272272343Sngie
273272343Sngie	if (fabs(exp(x) - 1.0) > 0.0)
274272343Sngie		atf_tc_fail_nonfatal("exp(-0.0) != 1.0");
275272343Sngie}
276272343Sngie
277272343SngieATF_TC(exp_zero_pos);
278272343SngieATF_TC_HEAD(exp_zero_pos, tc)
279272343Sngie{
280272343Sngie	atf_tc_set_md_var(tc, "descr", "Test exp(+0.0) == 1.0");
281272343Sngie}
282272343Sngie
283272343SngieATF_TC_BODY(exp_zero_pos, tc)
284272343Sngie{
285272343Sngie	const double x = 0.0L;
286272343Sngie
287272343Sngie	if (fabs(exp(x) - 1.0) > 0.0)
288272343Sngie		atf_tc_fail_nonfatal("exp(+0.0) != 1.0");
289272343Sngie}
290272343Sngie
291272343Sngie/*
292272343Sngie * expf(3)
293272343Sngie */
294272343SngieATF_TC(expf_nan);
295272343SngieATF_TC_HEAD(expf_nan, tc)
296272343Sngie{
297272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(NaN) == NaN");
298272343Sngie}
299272343Sngie
300272343SngieATF_TC_BODY(expf_nan, tc)
301272343Sngie{
302272343Sngie	const float x = 0.0L / 0.0L;
303272343Sngie
304272343Sngie	if (isnan(expf(x)) == 0)
305272343Sngie		atf_tc_fail_nonfatal("expf(NaN) != NaN");
306272343Sngie}
307272343Sngie
308272343SngieATF_TC(expf_inf_neg);
309272343SngieATF_TC_HEAD(expf_inf_neg, tc)
310272343Sngie{
311272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(-Inf) == +0.0");
312272343Sngie}
313272343Sngie
314272343SngieATF_TC_BODY(expf_inf_neg, tc)
315272343Sngie{
316272343Sngie	const float x = -1.0L / 0.0L;
317272343Sngie	float y = expf(x);
318272343Sngie
319272343Sngie	if (fabsf(y) > 0.0 || signbit(y) != 0)
320272343Sngie		atf_tc_fail_nonfatal("expf(-Inf) != +0.0");
321272343Sngie}
322272343Sngie
323272343SngieATF_TC(expf_inf_pos);
324272343SngieATF_TC_HEAD(expf_inf_pos, tc)
325272343Sngie{
326272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(+Inf) == +Inf");
327272343Sngie}
328272343Sngie
329272343SngieATF_TC_BODY(expf_inf_pos, tc)
330272343Sngie{
331272343Sngie	const float x = 1.0L / 0.0L;
332272343Sngie	float y = expf(x);
333272343Sngie
334272343Sngie	if (isinf(y) == 0 || signbit(y) != 0)
335272343Sngie		atf_tc_fail_nonfatal("expf(+Inf) != +Inf");
336272343Sngie}
337272343Sngie
338272343SngieATF_TC(expf_product);
339272343SngieATF_TC_HEAD(expf_product, tc)
340272343Sngie{
341272343Sngie	atf_tc_set_md_var(tc, "descr", "Test some selected expf(x)");
342272343Sngie}
343272343Sngie
344272343SngieATF_TC_BODY(expf_product, tc)
345272343Sngie{
346272343Sngie	float eps;
347272343Sngie	float x;
348272343Sngie	float y;
349272343Sngie	size_t i;
350272343Sngie
351272343Sngie	for (i = 0; i < __arraycount(exp_values); i++) {
352272343Sngie		x = exp_values[i].x;
353272343Sngie		y = exp_values[i].y;
354272343Sngie		eps = 1e-6 * exp_values[i].e;
355272343Sngie
356272343Sngie		if (fabsf(expf(x) - y) > eps)
357272343Sngie			atf_tc_fail_nonfatal("expf(%0.01f) != %18.18e", x, y);
358272343Sngie	}
359272343Sngie}
360272343Sngie
361272343SngieATF_TC(expf_zero_neg);
362272343SngieATF_TC_HEAD(expf_zero_neg, tc)
363272343Sngie{
364272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(-0.0) == 1.0");
365272343Sngie}
366272343Sngie
367272343SngieATF_TC_BODY(expf_zero_neg, tc)
368272343Sngie{
369272343Sngie	const float x = -0.0L;
370272343Sngie
371272343Sngie	if (fabsf(expf(x) - 1.0f) > 0.0)
372272343Sngie		atf_tc_fail_nonfatal("expf(-0.0) != 1.0");
373272343Sngie}
374272343Sngie
375272343SngieATF_TC(expf_zero_pos);
376272343SngieATF_TC_HEAD(expf_zero_pos, tc)
377272343Sngie{
378272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expf(+0.0) == 1.0");
379272343Sngie}
380272343Sngie
381272343SngieATF_TC_BODY(expf_zero_pos, tc)
382272343Sngie{
383272343Sngie	const float x = 0.0L;
384272343Sngie
385272343Sngie	if (fabsf(expf(x) - 1.0f) > 0.0)
386272343Sngie		atf_tc_fail_nonfatal("expf(+0.0) != 1.0");
387272343Sngie}
388272343Sngie
389272343Sngie/*
390272343Sngie * expm1(3)
391272343Sngie */
392272343SngieATF_TC(expm1_nan);
393272343SngieATF_TC_HEAD(expm1_nan, tc)
394272343Sngie{
395272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(NaN) == NaN");
396272343Sngie}
397272343Sngie
398272343SngieATF_TC_BODY(expm1_nan, tc)
399272343Sngie{
400272343Sngie	const double x = 0.0L / 0.0L;
401272343Sngie
402272343Sngie	if (isnan(expm1(x)) == 0)
403272343Sngie		atf_tc_fail_nonfatal("expm1(NaN) != NaN");
404272343Sngie}
405272343Sngie
406272343SngieATF_TC(expm1_inf_neg);
407272343SngieATF_TC_HEAD(expm1_inf_neg, tc)
408272343Sngie{
409272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(-Inf) == -1");
410272343Sngie}
411272343Sngie
412272343SngieATF_TC_BODY(expm1_inf_neg, tc)
413272343Sngie{
414272343Sngie	const double x = -1.0L / 0.0L;
415272343Sngie
416272343Sngie	if (expm1(x) != -1.0)
417272343Sngie		atf_tc_fail_nonfatal("expm1(-Inf) != -1.0");
418272343Sngie}
419272343Sngie
420272343SngieATF_TC(expm1_inf_pos);
421272343SngieATF_TC_HEAD(expm1_inf_pos, tc)
422272343Sngie{
423272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(+Inf) == +Inf");
424272343Sngie}
425272343Sngie
426272343SngieATF_TC_BODY(expm1_inf_pos, tc)
427272343Sngie{
428272343Sngie	const double x = 1.0L / 0.0L;
429272343Sngie	double y = expm1(x);
430272343Sngie
431272343Sngie	if (isinf(y) == 0 || signbit(y) != 0)
432272343Sngie		atf_tc_fail_nonfatal("expm1(+Inf) != +Inf");
433272343Sngie}
434272343Sngie
435272343SngieATF_TC(expm1_zero_neg);
436272343SngieATF_TC_HEAD(expm1_zero_neg, tc)
437272343Sngie{
438272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(-0.0) == -0.0");
439272343Sngie}
440272343Sngie
441272343SngieATF_TC_BODY(expm1_zero_neg, tc)
442272343Sngie{
443272343Sngie	const double x = -0.0L;
444272343Sngie	double y = expm1(x);
445272343Sngie
446272343Sngie	if (fabs(y) > 0.0 || signbit(y) == 0)
447272343Sngie		atf_tc_fail_nonfatal("expm1(-0.0) != -0.0");
448272343Sngie}
449272343Sngie
450272343SngieATF_TC(expm1_zero_pos);
451272343SngieATF_TC_HEAD(expm1_zero_pos, tc)
452272343Sngie{
453272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1(+0.0) == 1.0");
454272343Sngie}
455272343Sngie
456272343SngieATF_TC_BODY(expm1_zero_pos, tc)
457272343Sngie{
458272343Sngie	const double x = 0.0L;
459272343Sngie	double y = expm1(x);
460272343Sngie
461272343Sngie	if (fabs(y) > 0.0 || signbit(y) != 0)
462272343Sngie		atf_tc_fail_nonfatal("expm1(+0.0) != +0.0");
463272343Sngie}
464272343Sngie
465272343Sngie/*
466272343Sngie * expm1f(3)
467272343Sngie */
468272343SngieATF_TC(expm1f_nan);
469272343SngieATF_TC_HEAD(expm1f_nan, tc)
470272343Sngie{
471272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(NaN) == NaN");
472272343Sngie}
473272343Sngie
474272343SngieATF_TC_BODY(expm1f_nan, tc)
475272343Sngie{
476272343Sngie	const float x = 0.0L / 0.0L;
477272343Sngie
478272343Sngie	if (isnan(expm1f(x)) == 0)
479272343Sngie		atf_tc_fail_nonfatal("expm1f(NaN) != NaN");
480272343Sngie}
481272343Sngie
482272343SngieATF_TC(expm1f_inf_neg);
483272343SngieATF_TC_HEAD(expm1f_inf_neg, tc)
484272343Sngie{
485272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(-Inf) == -1");
486272343Sngie}
487272343Sngie
488272343SngieATF_TC_BODY(expm1f_inf_neg, tc)
489272343Sngie{
490272343Sngie	const float x = -1.0L / 0.0L;
491272343Sngie
492272343Sngie	if (expm1f(x) != -1.0)
493272343Sngie		atf_tc_fail_nonfatal("expm1f(-Inf) != -1.0");
494272343Sngie}
495272343Sngie
496272343SngieATF_TC(expm1f_inf_pos);
497272343SngieATF_TC_HEAD(expm1f_inf_pos, tc)
498272343Sngie{
499272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(+Inf) == +Inf");
500272343Sngie}
501272343Sngie
502272343SngieATF_TC_BODY(expm1f_inf_pos, tc)
503272343Sngie{
504272343Sngie	const float x = 1.0L / 0.0L;
505272343Sngie	float y = expm1f(x);
506272343Sngie
507272343Sngie	if (isinf(y) == 0 || signbit(y) != 0)
508272343Sngie		atf_tc_fail_nonfatal("expm1f(+Inf) != +Inf");
509272343Sngie}
510272343Sngie
511272343SngieATF_TC(expm1f_zero_neg);
512272343SngieATF_TC_HEAD(expm1f_zero_neg, tc)
513272343Sngie{
514272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(-0.0) == -0.0");
515272343Sngie}
516272343Sngie
517272343SngieATF_TC_BODY(expm1f_zero_neg, tc)
518272343Sngie{
519272343Sngie	const float x = -0.0L;
520272343Sngie	float y = expm1f(x);
521272343Sngie
522272343Sngie	if (fabsf(y) > 0.0 || signbit(y) == 0)
523272343Sngie		atf_tc_fail_nonfatal("expm1f(-0.0) != -0.0");
524272343Sngie}
525272343Sngie
526272343SngieATF_TC(expm1f_zero_pos);
527272343SngieATF_TC_HEAD(expm1f_zero_pos, tc)
528272343Sngie{
529272343Sngie	atf_tc_set_md_var(tc, "descr", "Test expm1f(+0.0) == 1.0");
530272343Sngie}
531272343Sngie
532272343SngieATF_TC_BODY(expm1f_zero_pos, tc)
533272343Sngie{
534272343Sngie	const float x = 0.0L;
535272343Sngie	float y = expm1f(x);
536272343Sngie
537272343Sngie	if (fabsf(y) > 0.0 || signbit(y) != 0)
538272343Sngie		atf_tc_fail_nonfatal("expm1f(+0.0) != +0.0");
539272343Sngie}
540272343Sngie
541272343SngieATF_TP_ADD_TCS(tp)
542272343Sngie{
543272343Sngie
544272343Sngie	ATF_TP_ADD_TC(tp, exp2_is_nan);
545272343Sngie	ATF_TP_ADD_TC(tp, exp2_is_plus_zero);
546272343Sngie	ATF_TP_ADD_TC(tp, exp2_values);
547272343Sngie	ATF_TP_ADD_TC(tp, exp2_powers);
548272343Sngie
549272343Sngie	ATF_TP_ADD_TC(tp, exp_nan);
550272343Sngie	ATF_TP_ADD_TC(tp, exp_inf_neg);
551272343Sngie	ATF_TP_ADD_TC(tp, exp_inf_pos);
552272343Sngie	ATF_TP_ADD_TC(tp, exp_product);
553272343Sngie	ATF_TP_ADD_TC(tp, exp_zero_neg);
554272343Sngie	ATF_TP_ADD_TC(tp, exp_zero_pos);
555272343Sngie
556272343Sngie	ATF_TP_ADD_TC(tp, expf_nan);
557272343Sngie	ATF_TP_ADD_TC(tp, expf_inf_neg);
558272343Sngie	ATF_TP_ADD_TC(tp, expf_inf_pos);
559272343Sngie	ATF_TP_ADD_TC(tp, expf_product);
560272343Sngie	ATF_TP_ADD_TC(tp, expf_zero_neg);
561272343Sngie	ATF_TP_ADD_TC(tp, expf_zero_pos);
562272343Sngie
563272343Sngie	ATF_TP_ADD_TC(tp, expm1_nan);
564272343Sngie	ATF_TP_ADD_TC(tp, expm1_inf_neg);
565272343Sngie	ATF_TP_ADD_TC(tp, expm1_inf_pos);
566272343Sngie	ATF_TP_ADD_TC(tp, expm1_zero_neg);
567272343Sngie	ATF_TP_ADD_TC(tp, expm1_zero_pos);
568272343Sngie
569272343Sngie	ATF_TP_ADD_TC(tp, expm1f_nan);
570272343Sngie	ATF_TP_ADD_TC(tp, expm1f_inf_neg);
571272343Sngie	ATF_TP_ADD_TC(tp, expm1f_inf_pos);
572272343Sngie	ATF_TP_ADD_TC(tp, expm1f_zero_neg);
573272343Sngie	ATF_TP_ADD_TC(tp, expm1f_zero_pos);
574272343Sngie
575272343Sngie	return atf_no_error();
576272343Sngie}
577