xref: /netbsd-src/tests/lib/libm/t_log.c (revision df44e1781c9ef8de32dd724a57d74a471e0d77d3)
1*df44e178Sriastradh /* $NetBSD: t_log.c,v 1.19 2024/07/17 14:52:13 riastradh Exp $ */
2a63adaf8Sjruoho 
3a63adaf8Sjruoho /*-
4a63adaf8Sjruoho  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5a63adaf8Sjruoho  * All rights reserved.
6a63adaf8Sjruoho  *
7a63adaf8Sjruoho  * This code is derived from software contributed to The NetBSD Foundation
8a63adaf8Sjruoho  * by Jukka Ruohonen.
9a63adaf8Sjruoho  *
10a63adaf8Sjruoho  * Redistribution and use in source and binary forms, with or without
11a63adaf8Sjruoho  * modification, are permitted provided that the following conditions
12a63adaf8Sjruoho  * are met:
13a63adaf8Sjruoho  * 1. Redistributions of source code must retain the above copyright
14a63adaf8Sjruoho  *    notice, this list of conditions and the following disclaimer.
15a63adaf8Sjruoho  * 2. Redistributions in binary form must reproduce the above copyright
16a63adaf8Sjruoho  *    notice, this list of conditions and the following disclaimer in the
17a63adaf8Sjruoho  *    documentation and/or other materials provided with the distribution.
18a63adaf8Sjruoho  *
19a63adaf8Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20a63adaf8Sjruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21a63adaf8Sjruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a63adaf8Sjruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23a63adaf8Sjruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24a63adaf8Sjruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25a63adaf8Sjruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26a63adaf8Sjruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27a63adaf8Sjruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28a63adaf8Sjruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29a63adaf8Sjruoho  * POSSIBILITY OF SUCH DAMAGE.
30a63adaf8Sjruoho  */
31a63adaf8Sjruoho #include <sys/cdefs.h>
32*df44e178Sriastradh __RCSID("$NetBSD: t_log.c,v 1.19 2024/07/17 14:52:13 riastradh Exp $");
332f3695baSriastradh 
342f3695baSriastradh #include <sys/types.h>
35a63adaf8Sjruoho 
36a63adaf8Sjruoho #include <atf-c.h>
3768f1ec4fSjruoho 
38d61c405bSriastradh #include <errno.h>
39a8a8e5f5Sriastradh #include <float.h>
407638c70bSjruoho #include <math.h>
4168f1ec4fSjruoho #include <stdio.h>
4268f1ec4fSjruoho #include <string.h>
43a63adaf8Sjruoho 
44d61c405bSriastradh #define	CHECK_EQ(i, f, x, y)						      \
45d61c405bSriastradh 	ATF_CHECK_EQ_MSG(f(x), y,					      \
46d61c405bSriastradh 	    "[%u] %s(%a=%.17g)=%a=%.17g, expected %a=%.17g",		      \
47d61c405bSriastradh 	    (i), #f, (double)(x), (double)(x), f(x), f(x),		      \
48d61c405bSriastradh 	    (double)(y), (double)(y))
49d61c405bSriastradh 
50d61c405bSriastradh #define	CHECKL_EQ(i, f, x, y)						      \
51d61c405bSriastradh 	ATF_CHECK_EQ_MSG(f(x), y,					      \
522f3695baSriastradh 	    "[%u] %s(%La=%.34Lg)=%La=%.34Lg, expected %La=%.34Lg",	      \
53d61c405bSriastradh 	    (i), #f, (long double)(x), (long double)(x), f(x), f(x),	      \
54d61c405bSriastradh 	    (long double)(y), (long double)(y))
55d61c405bSriastradh 
56d61c405bSriastradh #ifdef NAN
57d61c405bSriastradh 
58d61c405bSriastradh #define	CHECK_NAN(i, f, x)						      \
59d61c405bSriastradh 	ATF_CHECK_MSG(isnan(f(x)),					      \
60d61c405bSriastradh 	    "[%u] %s(%a=%.17g)=%a=%.17g, expected NaN",			      \
61d61c405bSriastradh 	    (i), #f, (x), (x), f(x), f(x))
62d61c405bSriastradh 
63d61c405bSriastradh #define	CHECKL_NAN(i, f, x)						      \
64d61c405bSriastradh 	ATF_CHECK_MSG(isnan(f(x)),					      \
652f3695baSriastradh 	    "[%u] %s(%La=%.34Lg)=%La=%.34Lg, expected NaN",		      \
66d61c405bSriastradh 	    (i), #f, (long double)(x), (long double)(x), f(x), f(x))
67d61c405bSriastradh 
68d61c405bSriastradh #else  /* !defined(NAN) */
69d61c405bSriastradh 
70d61c405bSriastradh #define	CHECK_NAN(i, f, x) do						      \
71d61c405bSriastradh {									      \
72d61c405bSriastradh 	int _checknan_error;						      \
73d61c405bSriastradh 	double _checknan_result;					      \
74d61c405bSriastradh 	errno = 0;							      \
75d61c405bSriastradh 	_checknan_result = f(x);					      \
76d61c405bSriastradh 	_checknan_error = errno;					      \
77d61c405bSriastradh 	ATF_CHECK_EQ_MSG(errno, EDOM,					      \
78d61c405bSriastradh 	    "[%u] %s(%a=%.17g)=%a=%.17g errno=%d, expected EDOM=%d",	      \
79d61c405bSriastradh 	    (i), #f, (double)(x), (double)(x),				      \
80d61c405bSriastradh 	    _checknan_result, _checknan_result,				      \
81d61c405bSriastradh 	    _checknan_error, EDOM);					      \
82d61c405bSriastradh } while (0)
83d61c405bSriastradh 
84d61c405bSriastradh #define	CHECKL_NAN(i, f, x) do						      \
85d61c405bSriastradh {									      \
86d61c405bSriastradh 	int _checknan_error;						      \
87d61c405bSriastradh 	long double _checknan_result;					      \
88d61c405bSriastradh 	errno = 0;							      \
89d61c405bSriastradh 	_checknan_result = f(x);					      \
90d61c405bSriastradh 	_checknan_error = errno;					      \
91d61c405bSriastradh 	ATF_CHECK_EQ_MSG(errno, EDOM,					      \
922f3695baSriastradh 	    "[%u] %s(%La=%.34Lg)=%La=%.34Lg errno=%d, expected EDOM=%d",      \
93d61c405bSriastradh 	    (i), #f, (long double)(x), (long double)(x),		      \
94d61c405bSriastradh 	    _checknan_result, _checknan_result,				      \
95d61c405bSriastradh 	    _checknan_error, EDOM);					      \
96d61c405bSriastradh } while (0)
97d61c405bSriastradh 
98d61c405bSriastradh #endif	/* NAN */
99d61c405bSriastradh 
100d61c405bSriastradh static const float logf_invalid[] = {
101d61c405bSriastradh #ifdef NAN
102d61c405bSriastradh 	NAN,
103d61c405bSriastradh #endif
104d61c405bSriastradh 	-HUGE_VALF,
105d61c405bSriastradh 	-FLT_MAX,
106d61c405bSriastradh 	-10,
107d61c405bSriastradh 	-1,
108d61c405bSriastradh 	-FLT_EPSILON,
109d61c405bSriastradh 	-FLT_MIN,
110d61c405bSriastradh #ifdef FLT_DENORM_MIN
111d61c405bSriastradh 	-FLT_DENORM_MIN,
112d61c405bSriastradh #endif
113d61c405bSriastradh };
114d61c405bSriastradh 
115d61c405bSriastradh static const double log_invalid[] = {
116d61c405bSriastradh #ifdef NAN
117d61c405bSriastradh 	NAN,
118d61c405bSriastradh #endif
119d61c405bSriastradh 	-HUGE_VAL,
120d61c405bSriastradh 	-DBL_MAX,
121d61c405bSriastradh 	-10,
122d61c405bSriastradh 	-1,
123d61c405bSriastradh 	-DBL_EPSILON,
124d61c405bSriastradh 	-DBL_MIN,
125d61c405bSriastradh #ifdef DBL_DENORM_MIN
126d61c405bSriastradh 	-DBL_DENORM_MIN,
127d61c405bSriastradh #endif
128d61c405bSriastradh };
129d61c405bSriastradh 
130d61c405bSriastradh static const long double logl_invalid[] = {
131d61c405bSriastradh #ifdef NAN
132d61c405bSriastradh 	NAN,
133d61c405bSriastradh #endif
134d61c405bSriastradh 	-HUGE_VALL,
135d61c405bSriastradh 	-LDBL_MAX,
136d61c405bSriastradh 	-10,
137d61c405bSriastradh 	-1,
138d61c405bSriastradh 	-LDBL_EPSILON,
139d61c405bSriastradh 	-LDBL_MIN,
140d61c405bSriastradh #ifdef LDBL_DENORM_MIN
141d61c405bSriastradh 	-LDBL_DENORM_MIN,
142d61c405bSriastradh #endif
143d61c405bSriastradh };
144d61c405bSriastradh 
145d61c405bSriastradh static const float log1pf_invalid[] = {
146d61c405bSriastradh #ifdef NAN
147d61c405bSriastradh 	NAN,
148d61c405bSriastradh #endif
149d61c405bSriastradh 	-HUGE_VALF,
150d61c405bSriastradh 	-FLT_MAX,
151d61c405bSriastradh 	-10,
152d61c405bSriastradh 	-1 - FLT_EPSILON,
153d61c405bSriastradh };
154d61c405bSriastradh 
155d61c405bSriastradh static const double log1p_invalid[] = {
156d61c405bSriastradh #ifdef NAN
157d61c405bSriastradh 	NAN,
158d61c405bSriastradh #endif
159d61c405bSriastradh 	-HUGE_VAL,
160d61c405bSriastradh 	-DBL_MAX,
161d61c405bSriastradh 	-10,
162d61c405bSriastradh 	-1 - DBL_EPSILON,
163d61c405bSriastradh };
164d61c405bSriastradh 
165d61c405bSriastradh static const long double log1pl_invalid[] = {
166d61c405bSriastradh #ifdef NAN
167d61c405bSriastradh 	NAN,
168d61c405bSriastradh #endif
169d61c405bSriastradh 	-HUGE_VALL,
170d61c405bSriastradh 	-LDBL_MAX,
171d61c405bSriastradh 	-10,
172d61c405bSriastradh 	-1 - LDBL_EPSILON,
173d61c405bSriastradh };
174d61c405bSriastradh 
1757638c70bSjruoho /*
1767638c70bSjruoho  * log10(3)
1777638c70bSjruoho  */
178d61c405bSriastradh static const struct {
179d61c405bSriastradh 	float x, y;
180d61c405bSriastradh } log10f_exact[] = {
181d61c405bSriastradh 	{ 1, 0 },
182d61c405bSriastradh 	{ 10, 1 },
183d61c405bSriastradh 	{ 100, 2 },
184d61c405bSriastradh };
185d61c405bSriastradh 
186d61c405bSriastradh ATF_TC(log10_invalid);
187d61c405bSriastradh ATF_TC_HEAD(log10_invalid, tc)
1889273f704Sjruoho {
189d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on invalid inputs");
190d61c405bSriastradh }
191d61c405bSriastradh ATF_TC_BODY(log10_invalid, tc)
192d61c405bSriastradh {
193d61c405bSriastradh 	unsigned i;
194d61c405bSriastradh 
195d61c405bSriastradh 	for (i = 0; i < __arraycount(logf_invalid); i++) {
196d61c405bSriastradh 		CHECK_NAN(i, log10f, logf_invalid[i]);
197d61c405bSriastradh 		CHECK_NAN(i, log10, logf_invalid[i]);
198d61c405bSriastradh 		CHECKL_NAN(i, log10l, logf_invalid[i]);
1999273f704Sjruoho 	}
2009273f704Sjruoho 
201d61c405bSriastradh 	for (i = 0; i < __arraycount(log_invalid); i++) {
202d61c405bSriastradh 		CHECK_NAN(i, log10, log_invalid[i]);
203d61c405bSriastradh 		CHECKL_NAN(i, log10l, log_invalid[i]);
2049273f704Sjruoho 	}
2059273f704Sjruoho 
206d61c405bSriastradh 	for (i = 0; i < __arraycount(logl_invalid); i++) {
207d61c405bSriastradh 		CHECKL_NAN(i, log10l, logl_invalid[i]);
208d61c405bSriastradh 	}
2097638c70bSjruoho }
2107638c70bSjruoho 
211d61c405bSriastradh ATF_TC(log10_zero);
212d61c405bSriastradh ATF_TC_HEAD(log10_zero, tc)
2137638c70bSjruoho {
214d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on zero");
215d61c405bSriastradh }
216d61c405bSriastradh ATF_TC_BODY(log10_zero, tc)
217d61c405bSriastradh {
2187638c70bSjruoho 
219d61c405bSriastradh 	CHECK_EQ(0, log10f, +0., -HUGE_VALF);
220d61c405bSriastradh 	CHECK_EQ(0, log10, +0., -HUGE_VAL);
221d61c405bSriastradh 	CHECKL_EQ(0, log10l, +0., -HUGE_VALL);
222d61c405bSriastradh 
223d61c405bSriastradh 	CHECK_EQ(1, log10f, -0., -HUGE_VALF);
224d61c405bSriastradh 	CHECK_EQ(1, log10, -0., -HUGE_VAL);
225d61c405bSriastradh 	CHECKL_EQ(1, log10l, -0., -HUGE_VALL);
2267638c70bSjruoho }
2277638c70bSjruoho 
228d61c405bSriastradh ATF_TC(log10_exact);
229d61c405bSriastradh ATF_TC_HEAD(log10_exact, tc)
2307638c70bSjruoho {
231d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l exact cases");
232d61c405bSriastradh }
233d61c405bSriastradh ATF_TC_BODY(log10_exact, tc)
234d61c405bSriastradh {
235d61c405bSriastradh 	unsigned i;
236d61c405bSriastradh 
237d61c405bSriastradh 	ATF_CHECK_EQ(signbit(log10f(1)), 0);
238d61c405bSriastradh 	ATF_CHECK_EQ(signbit(log10(1)), 0);
239d61c405bSriastradh 	ATF_CHECK_EQ(signbit(log10l(1)), 0);
240d61c405bSriastradh 
241d61c405bSriastradh 	for (i = 0; i < __arraycount(log10f_exact); i++) {
242d61c405bSriastradh 		const float x = log10f_exact[i].x;
243d61c405bSriastradh 		const float y = log10f_exact[i].y;
244d61c405bSriastradh 
245d61c405bSriastradh 		CHECK_EQ(i, log10f, x, y);
246d61c405bSriastradh 		CHECK_EQ(i, log10, x, y);
247d61c405bSriastradh 		CHECKL_EQ(i, log10l, x, y);
248d61c405bSriastradh 	}
2497638c70bSjruoho }
2507638c70bSjruoho 
2512f3695baSriastradh ATF_TC(log10_approx);
2522f3695baSriastradh ATF_TC_HEAD(log10_approx, tc)
2532f3695baSriastradh {
2542f3695baSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l approximate cases");
2552f3695baSriastradh }
2562f3695baSriastradh ATF_TC_BODY(log10_approx, tc)
2572f3695baSriastradh {
2582f3695baSriastradh 	volatile long double e =
2592f3695baSriastradh 	    2.7182818284590452353602874713526624977572470937L;
2602f3695baSriastradh 	volatile long double e2 =
2612f3695baSriastradh 	    7.3890560989306502272304274605750078131803155705519L;
2622f3695baSriastradh 	volatile long double log10e =
2632f3695baSriastradh 	    0.43429448190325182765112891891660508229439700580367L;
2642f3695baSriastradh 	volatile long double log10e2 =
2652f3695baSriastradh 	    2*0.43429448190325182765112891891660508229439700580367L;
2662f3695baSriastradh 
2672f3695baSriastradh 	ATF_CHECK_MSG((fabsf((log10f(e) - (float)log10e)/(float)log10e) <
2682f3695baSriastradh 		2*FLT_EPSILON),
2692f3695baSriastradh 	    "log10f(e)=%a=%.8g expected %a=%.8g",
2702f3695baSriastradh 	    log10f(e), log10f(e), (float)log10e, (float)log10e);
2712f3695baSriastradh 	ATF_CHECK_MSG((fabs((log10(e) - (double)log10e)/(double)log10e) <
2722f3695baSriastradh 		2*DBL_EPSILON),
2732f3695baSriastradh 	    "log10(e)=%a=%.17g expected %a=%.17g",
2742f3695baSriastradh 	    log10(e), log10(e), (double)log10e, (double)log10e);
2752f3695baSriastradh 	ATF_CHECK_MSG((fabsl((log10l(e) - log10e)/log10e) < 2*LDBL_EPSILON),
2762f3695baSriastradh 	    "log10l(e)=%La=%.34Lg expected %La=%.34Lg",
2772f3695baSriastradh 	    log10l(e), log10l(e), log10e, log10e);
2782f3695baSriastradh 
2792f3695baSriastradh 	ATF_CHECK_MSG((fabsf((log10f(e2) - (float)log10e2)/(float)log10e2) <
2802f3695baSriastradh 		2*FLT_EPSILON),
2812f3695baSriastradh 	    "log10f(e^2)=%a=%.8g expected %a=%.8g",
2822f3695baSriastradh 	    log10f(e2), log10f(e2), (float)log10e2, (float)log10e2);
2832f3695baSriastradh 	ATF_CHECK_MSG((fabs((log10(e2) - (double)log10e2)/(double)log10e2) <
2842f3695baSriastradh 		2*DBL_EPSILON),
2852f3695baSriastradh 	    "log10(e^2)=%a=%.17g expected %a=%.17g",
2862f3695baSriastradh 	    log10(e2), log10(e2), (double)log10e2, (double)log10e2);
2872f3695baSriastradh 	ATF_CHECK_MSG((fabsl((log10l(e2) - log10e2)/log10e2) < 2*LDBL_EPSILON),
2882f3695baSriastradh 	    "log10l(e^2)=%La=%.34Lg expected %La=%.34Lg",
2892f3695baSriastradh 	    log10l(e2), log10l(e2), log10e2, log10e2);
2902f3695baSriastradh }
2912f3695baSriastradh 
292d61c405bSriastradh ATF_TC(log10_inf);
293d61c405bSriastradh ATF_TC_HEAD(log10_inf, tc)
2947638c70bSjruoho {
295d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on +infinity");
2967638c70bSjruoho }
297d61c405bSriastradh ATF_TC_BODY(log10_inf, tc)
2987638c70bSjruoho {
2997638c70bSjruoho 
300d61c405bSriastradh 	if (!isinf(INFINITY))
301d61c405bSriastradh 		atf_tc_skip("no infinities on this architecture");
3027638c70bSjruoho 
303d61c405bSriastradh 	CHECK_EQ(0, log10f, INFINITY, INFINITY);
304d61c405bSriastradh 	CHECK_EQ(0, log10, INFINITY, INFINITY);
305d61c405bSriastradh 	CHECKL_EQ(0, log10l, INFINITY, INFINITY);
3067638c70bSjruoho }
3077638c70bSjruoho 
3087638c70bSjruoho /*
3097638c70bSjruoho  * log1p(3)
3107638c70bSjruoho  */
311d61c405bSriastradh 
312d61c405bSriastradh ATF_TC(log1p_invalid);
313d61c405bSriastradh ATF_TC_HEAD(log1p_invalid, tc)
3147638c70bSjruoho {
315d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on invalid inputs");
316d61c405bSriastradh }
317d61c405bSriastradh ATF_TC_BODY(log1p_invalid, tc)
318d61c405bSriastradh {
319d61c405bSriastradh 	unsigned i;
320d61c405bSriastradh 
321d61c405bSriastradh 	for (i = 0; i < __arraycount(log1pf_invalid); i++) {
322d61c405bSriastradh 		CHECK_NAN(i, log1pf, log1pf_invalid[i]);
323d61c405bSriastradh 		CHECK_NAN(i, log1p, log1pf_invalid[i]);
324d61c405bSriastradh 		CHECKL_NAN(i, log1pl, log1pf_invalid[i]);
3257638c70bSjruoho 	}
3267638c70bSjruoho 
327d61c405bSriastradh 	for (i = 0; i < __arraycount(log1p_invalid); i++) {
328d61c405bSriastradh 		CHECK_NAN(i, log1p, log1p_invalid[i]);
329d61c405bSriastradh 		CHECKL_NAN(i, log1pl, log1p_invalid[i]);
3307638c70bSjruoho 	}
3317638c70bSjruoho 
332d61c405bSriastradh 	for (i = 0; i < __arraycount(log1pl_invalid); i++) {
333d61c405bSriastradh 		CHECKL_NAN(i, log1pl, log1pl_invalid[i]);
334d61c405bSriastradh 	}
3357638c70bSjruoho }
3367638c70bSjruoho 
337d61c405bSriastradh ATF_TC(log1p_neg_one);
338d61c405bSriastradh ATF_TC_HEAD(log1p_neg_one, tc)
3397638c70bSjruoho {
340d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on -1");
341d61c405bSriastradh }
342d61c405bSriastradh ATF_TC_BODY(log1p_neg_one, tc)
343d61c405bSriastradh {
3447638c70bSjruoho 
345d61c405bSriastradh 	CHECK_EQ(0, log1pf, -1., -HUGE_VALF);
346d61c405bSriastradh 	CHECK_EQ(0, log1p, -1., -HUGE_VAL);
347d61c405bSriastradh 	CHECKL_EQ(0, log1pl, -1., -HUGE_VALL);
3487638c70bSjruoho }
3497638c70bSjruoho 
350d61c405bSriastradh ATF_TC(log1p_exact);
351d61c405bSriastradh ATF_TC_HEAD(log1p_exact, tc)
3527638c70bSjruoho {
353d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l exact cases");
3547638c70bSjruoho }
355d61c405bSriastradh ATF_TC_BODY(log1p_exact, tc)
3567638c70bSjruoho {
3577638c70bSjruoho 
3582f3695baSriastradh 	CHECK_EQ(0, log1pf, -FLT_MIN, -FLT_MIN);
3592f3695baSriastradh 	CHECK_EQ(0, log1p, -DBL_MIN, -DBL_MIN);
3602f3695baSriastradh 	CHECKL_EQ(01, log1pl, -LDBL_MIN, -LDBL_MIN);
3612f3695baSriastradh 
3622f3695baSriastradh 	CHECK_EQ(1, log1pf, -0., 0);
3632f3695baSriastradh 	CHECK_EQ(1, log1p, -0., 0);
3642f3695baSriastradh 	CHECKL_EQ(1, log1pl, -0., 0);
3652f3695baSriastradh 
3662f3695baSriastradh 	CHECK_EQ(2, log1pf, +0., 0);
3672f3695baSriastradh 	CHECK_EQ(2, log1p, +0., 0);
3682f3695baSriastradh 	CHECKL_EQ(2, log1pl, +0., 0);
3692f3695baSriastradh 
370*df44e178Sriastradh #ifdef __i386__
371*df44e178Sriastradh 	atf_tc_expect_fail("PR port-i386/58434: single-float functions"
372*df44e178Sriastradh 	    " sometimes return surprisingly much precision");
373*df44e178Sriastradh #endif
3742f3695baSriastradh 	CHECK_EQ(3, log1pf, 1, logf(2));
375*df44e178Sriastradh #ifdef __i386__
376*df44e178Sriastradh 	atf_tc_expect_pass();
377*df44e178Sriastradh #endif
3782f3695baSriastradh 	CHECK_EQ(3, log1p, 1, log(2));
3792f3695baSriastradh 	CHECKL_EQ(3, log1pl, 1, logl(2));
3802f3695baSriastradh }
3812f3695baSriastradh 
3822f3695baSriastradh ATF_TC(log1p_approx);
3832f3695baSriastradh ATF_TC_HEAD(log1p_approx, tc)
3842f3695baSriastradh {
3852f3695baSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l approximate cases");
3862f3695baSriastradh }
3872f3695baSriastradh ATF_TC_BODY(log1p_approx, tc)
3882f3695baSriastradh {
3892f3695baSriastradh 	volatile long double em1 =	/* exp(1) - 1 */
3902f3695baSriastradh 	    1.7182818284590452353602874713526624977572470937L;
3912f3695baSriastradh 	volatile long double e2m1 =	/* exp(2) - 1 */
3922f3695baSriastradh 	    6.3890560989306502272304274605750078131803155705519L;
3932f3695baSriastradh 
3947638c70bSjruoho 	/*
3952f3695baSriastradh 	 * Approximation is close enough that equality of the rounded
3962f3695baSriastradh 	 * output had better hold.
3977638c70bSjruoho 	 */
398d61c405bSriastradh #ifdef FLT_DENORM_MIN
399d61c405bSriastradh 	CHECK_EQ(0, log1pf, -FLT_DENORM_MIN, -FLT_DENORM_MIN);
400d61c405bSriastradh #endif
401d61c405bSriastradh #ifdef DBL_DENORM_MIN
402d61c405bSriastradh 	CHECK_EQ(0, log1p, -DBL_DENORM_MIN, -DBL_DENORM_MIN);
403d61c405bSriastradh #endif
404d61c405bSriastradh #ifdef LDBL_DENORM_MIN
405d61c405bSriastradh 	CHECKL_EQ(0, log1pl, -LDBL_DENORM_MIN, -LDBL_DENORM_MIN);
406d61c405bSriastradh #endif
407d61c405bSriastradh 
4082f3695baSriastradh 	ATF_CHECK_MSG(fabsf((log1pf(em1) - 1)/1) < 2*FLT_EPSILON,
4092f3695baSriastradh 	    "log1pf(e)=%a=%.8g", log1pf(em1), log1pf(em1));
4102f3695baSriastradh 	ATF_CHECK_MSG(fabs((log1p(em1) - 1)/1) < 2*DBL_EPSILON,
4112f3695baSriastradh 	    "log1p(e)=%a=%.17g", log1p(em1), log1p(em1));
4122f3695baSriastradh 	ATF_CHECK_MSG(fabsl((log1pl(em1) - 1)/1) < 2*LDBL_EPSILON,
4132f3695baSriastradh 	    "log1pl(e)=%La=%.34Lg", log1pl(em1), log1pl(em1));
414d61c405bSriastradh 
4152f3695baSriastradh 	ATF_CHECK_MSG(fabsf((log1pf(e2m1) - 2)/2) < 2*FLT_EPSILON,
4162f3695baSriastradh 	    "log1pf(e^2)=%a=%.8g", log1pf(em1), log1pf(em1));
4172f3695baSriastradh 	ATF_CHECK_MSG(fabs((log1p(e2m1) - 2)/2) < 2*DBL_EPSILON,
4182f3695baSriastradh 	    "log1p(e^2)=%a=%.17g", log1p(em1), log1p(em1));
4192f3695baSriastradh 	ATF_CHECK_MSG(fabsl((log1pl(e2m1) - 2)/2) < 2*LDBL_EPSILON,
4202f3695baSriastradh 	    "log1pl(e^2)=%La=%.34Lg", log1pl(em1), log1pl(em1));
4217638c70bSjruoho }
4227638c70bSjruoho 
423d61c405bSriastradh ATF_TC(log1p_inf);
424d61c405bSriastradh ATF_TC_HEAD(log1p_inf, tc)
4257638c70bSjruoho {
426d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on +infinity");
4277638c70bSjruoho }
428d61c405bSriastradh ATF_TC_BODY(log1p_inf, tc)
4297638c70bSjruoho {
4307638c70bSjruoho 
431d61c405bSriastradh 	if (!isinf(INFINITY))
432d61c405bSriastradh 		atf_tc_skip("no infinities on this architecture");
4337638c70bSjruoho 
434d61c405bSriastradh 	CHECK_EQ(0, log1pf, INFINITY, INFINITY);
435d61c405bSriastradh 	CHECK_EQ(0, log1p, INFINITY, INFINITY);
436d61c405bSriastradh 	CHECKL_EQ(0, log1pl, INFINITY, INFINITY);
4377638c70bSjruoho }
4387638c70bSjruoho 
4397638c70bSjruoho /*
4407638c70bSjruoho  * log2(3)
4417638c70bSjruoho  */
442d61c405bSriastradh static const struct {
443d61c405bSriastradh 	float x, y;
444d61c405bSriastradh } log2f_exact[] = {
445d61c405bSriastradh #ifdef FLT_DENORM_MIN
446d61c405bSriastradh 	{ FLT_DENORM_MIN, FLT_MIN_EXP - FLT_MANT_DIG },
447d61c405bSriastradh #endif
448d61c405bSriastradh 	{ FLT_MIN, FLT_MIN_EXP - 1 },
449d61c405bSriastradh 	{ 0.25, -2 },
450d61c405bSriastradh 	{ 0.5, -1 },
451d61c405bSriastradh 	{ 1, 0 },
452d61c405bSriastradh 	{ 2, 1 },
453d61c405bSriastradh 	{ 4, 2 },
454d61c405bSriastradh 	{ 8, 3 },
455d61c405bSriastradh 	{ 1 << FLT_MANT_DIG, FLT_MANT_DIG },
456d61c405bSriastradh 	{ (float)(1 << FLT_MANT_DIG) * (1 << FLT_MANT_DIG),
457d61c405bSriastradh 	  2*FLT_MANT_DIG },
458d61c405bSriastradh };
459d61c405bSriastradh static const struct {
460d61c405bSriastradh 	double x, y;
461d61c405bSriastradh } log2_exact[] = {
462d61c405bSriastradh #ifdef DBL_DENORM_MIN
463d61c405bSriastradh 	{ DBL_DENORM_MIN, DBL_MIN_EXP - DBL_MANT_DIG },
464d61c405bSriastradh #endif
465d61c405bSriastradh 	{ DBL_MIN, DBL_MIN_EXP - 1 },
466d61c405bSriastradh 	{ (uint64_t)1 << DBL_MANT_DIG, DBL_MANT_DIG },
467d61c405bSriastradh 	{ ((double)((uint64_t)1 << DBL_MANT_DIG) *
468d61c405bSriastradh 		    ((uint64_t)1 << DBL_MANT_DIG)),
469d61c405bSriastradh 	  2*DBL_MANT_DIG },
470d61c405bSriastradh };
471d61c405bSriastradh 
472d61c405bSriastradh static const struct {
473d61c405bSriastradh 	long double x, y;
474d61c405bSriastradh } log2l_exact[] = {
475d61c405bSriastradh #ifdef LDBL_DENORM_MIN
476d61c405bSriastradh 	{ LDBL_DENORM_MIN, LDBL_MIN_EXP - LDBL_MANT_DIG },
477d61c405bSriastradh #endif
478d61c405bSriastradh 	{ LDBL_MIN, LDBL_MIN_EXP - 1 },
479d61c405bSriastradh 	{ ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
480d61c405bSriastradh 		    ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))),
481d61c405bSriastradh 	  LDBL_MANT_DIG },
482d61c405bSriastradh 	{ (((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
483d61c405bSriastradh 			((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))) *
484d61c405bSriastradh 		    ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
485d61c405bSriastradh 			((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2)))),
486d61c405bSriastradh 	  2*LDBL_MANT_DIG },
487d61c405bSriastradh };
488d61c405bSriastradh 
489d61c405bSriastradh ATF_TC(log2_invalid);
490d61c405bSriastradh ATF_TC_HEAD(log2_invalid, tc)
4919273f704Sjruoho {
492d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on invalid inputs");
493d61c405bSriastradh }
494d61c405bSriastradh ATF_TC_BODY(log2_invalid, tc)
495d61c405bSriastradh {
496d61c405bSriastradh 	unsigned i;
497d61c405bSriastradh 
498d61c405bSriastradh 	for (i = 0; i < __arraycount(logf_invalid); i++) {
499d61c405bSriastradh 		CHECK_NAN(i, log2f, logf_invalid[i]);
500d61c405bSriastradh 		CHECK_NAN(i, log2, logf_invalid[i]);
501d61c405bSriastradh 		CHECKL_NAN(i, log2l, logf_invalid[i]);
5029273f704Sjruoho 	}
5039273f704Sjruoho 
504d61c405bSriastradh 	for (i = 0; i < __arraycount(log_invalid); i++) {
505d61c405bSriastradh 		CHECK_NAN(i, log2, log_invalid[i]);
506d61c405bSriastradh 		CHECKL_NAN(i, log2l, log_invalid[i]);
5079273f704Sjruoho 	}
5089273f704Sjruoho 
509d61c405bSriastradh 	for (i = 0; i < __arraycount(logl_invalid); i++) {
510d61c405bSriastradh 		CHECKL_NAN(i, log2l, logl_invalid[i]);
511d61c405bSriastradh 	}
5127638c70bSjruoho }
5137638c70bSjruoho 
514d61c405bSriastradh ATF_TC(log2_zero);
515d61c405bSriastradh ATF_TC_HEAD(log2_zero, tc)
5167638c70bSjruoho {
517d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on zero");
518d61c405bSriastradh }
519d61c405bSriastradh ATF_TC_BODY(log2_zero, tc)
520d61c405bSriastradh {
5217638c70bSjruoho 
522d61c405bSriastradh 	CHECK_EQ(0, log2f, +0., -HUGE_VALF);
523d61c405bSriastradh 	CHECK_EQ(0, log2, +0., -HUGE_VAL);
524d61c405bSriastradh 	CHECKL_EQ(0, log2l, +0., -HUGE_VALL);
525d61c405bSriastradh 
526d61c405bSriastradh 	CHECK_EQ(1, log2f, -0., -HUGE_VALF);
527d61c405bSriastradh 	CHECK_EQ(1, log2, -0., -HUGE_VAL);
528d61c405bSriastradh 	CHECKL_EQ(1, log2l, -0., -HUGE_VALL);
5297638c70bSjruoho }
5307638c70bSjruoho 
531d61c405bSriastradh ATF_TC(log2_exact);
532d61c405bSriastradh ATF_TC_HEAD(log2_exact, tc)
5337638c70bSjruoho {
534d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l exact cases");
535d61c405bSriastradh }
536d61c405bSriastradh ATF_TC_BODY(log2_exact, tc)
537d61c405bSriastradh {
538d61c405bSriastradh 	unsigned i;
539d61c405bSriastradh 
540d61c405bSriastradh 	ATF_CHECK_EQ(signbit(log2f(1)), 0);
541d61c405bSriastradh 	ATF_CHECK_EQ(signbit(log2(1)), 0);
542d61c405bSriastradh 	ATF_CHECK_EQ(signbit(log2l(1)), 0);
543d61c405bSriastradh 
544d61c405bSriastradh 	for (i = 0; i < __arraycount(log2f_exact); i++) {
545d61c405bSriastradh 		const float x = log2f_exact[i].x;
546d61c405bSriastradh 		const float y = log2f_exact[i].y;
547d61c405bSriastradh 
548d61c405bSriastradh 		CHECK_EQ(i, log2f, x, y);
549d61c405bSriastradh 		CHECK_EQ(i, log2, x, y);
550d61c405bSriastradh 		CHECKL_EQ(i, log2l, x, y);
5517638c70bSjruoho 	}
5527638c70bSjruoho 
553d61c405bSriastradh 	for (i = 0; i < __arraycount(log2_exact); i++) {
554d61c405bSriastradh 		const double x = log2_exact[i].x;
555d61c405bSriastradh 		const double y = log2_exact[i].y;
5567638c70bSjruoho 
557d61c405bSriastradh 		CHECK_EQ(i, log2, x, y);
558d61c405bSriastradh 		CHECKL_EQ(i, log2l, x, y);
5597638c70bSjruoho 	}
5607638c70bSjruoho 
561d61c405bSriastradh 	for (i = 0; i < __arraycount(log2l_exact); i++) {
562d61c405bSriastradh 		const long double x = log2l_exact[i].x;
563d61c405bSriastradh 		const long double y = log2l_exact[i].y;
564d61c405bSriastradh 
565d61c405bSriastradh 		CHECKL_EQ(i, log2l, x, y);
566d61c405bSriastradh 	}
5677638c70bSjruoho }
5687638c70bSjruoho 
5692f3695baSriastradh ATF_TC(log2_approx);
5702f3695baSriastradh ATF_TC_HEAD(log2_approx, tc)
5712f3695baSriastradh {
5722f3695baSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l approximate cases");
5732f3695baSriastradh }
5742f3695baSriastradh ATF_TC_BODY(log2_approx, tc)
5752f3695baSriastradh {
5762f3695baSriastradh 	volatile long double e =
5772f3695baSriastradh 	    2.7182818284590452353602874713526624977572470937L;
5782f3695baSriastradh 	volatile long double e2 =
5792f3695baSriastradh 	    7.3890560989306502272304274605750078131803155705519L;
5802f3695baSriastradh 	volatile long double log2e =
5812f3695baSriastradh 	    1.442695040888963407359924681001892137426645954153L;
5822f3695baSriastradh 	volatile long double log2e2 =
5832f3695baSriastradh 	    2*1.442695040888963407359924681001892137426645954153L;
5842f3695baSriastradh 
5852f3695baSriastradh 	ATF_CHECK_MSG((fabsf((log2f(e) - (float)log2e)/(float)log2e) <
5862f3695baSriastradh 		2*FLT_EPSILON),
5872f3695baSriastradh 	    "log2f(e)=%a=%.8g expected %a=%.8g",
5882f3695baSriastradh 	    log2f(e), log2f(e), (float)log2e, (float)log2e);
5892f3695baSriastradh 	ATF_CHECK_MSG((fabs((log2(e) - (double)log2e)/(double)log2e) <
5902f3695baSriastradh 		2*DBL_EPSILON),
5912f3695baSriastradh 	    "log2(e)=%a=%.17g expected %a=%.17g",
5922f3695baSriastradh 	    log2(e), log2(e), (double)log2e, (double)log2e);
5932f3695baSriastradh 	ATF_CHECK_MSG((fabsl((log2l(e) - log2e)/log2e) < 2*LDBL_EPSILON),
5942f3695baSriastradh 	    "log2l(e)=%La=%.34Lg expected %La=%.34Lg",
5952f3695baSriastradh 	    log2l(e), log2l(e), log2e, log2e);
5962f3695baSriastradh 
5972f3695baSriastradh 	ATF_CHECK_MSG((fabsf((log2f(e2) - (float)log2e2)/(float)log2e2) <
5982f3695baSriastradh 		2*FLT_EPSILON),
5992f3695baSriastradh 	    "log2f(e^2)=%a=%.8g expected %a=%.8g",
6002f3695baSriastradh 	    log2f(e2), log2f(e2), (float)log2e2, (float)log2e2);
6012f3695baSriastradh 	ATF_CHECK_MSG((fabs((log2(e2) - (double)log2e2)/(double)log2e2) <
6022f3695baSriastradh 		2*DBL_EPSILON),
6032f3695baSriastradh 	    "log2(e^2)=%a=%.17g expected %a=%.17g",
6042f3695baSriastradh 	    log2(e2), log2(e2), (double)log2e2, (double)log2e2);
6052f3695baSriastradh 	ATF_CHECK_MSG((fabsl((log2l(e2) - log2e2)/log2e2) < 2*LDBL_EPSILON),
6062f3695baSriastradh 	    "log2l(e^2)=%La=%.34Lg expected %La=%.34Lg",
6072f3695baSriastradh 	    log2l(e2), log2l(e2), log2e2, log2e2);
6082f3695baSriastradh }
6092f3695baSriastradh 
610d61c405bSriastradh ATF_TC(log2_inf);
611d61c405bSriastradh ATF_TC_HEAD(log2_inf, tc)
6127638c70bSjruoho {
613d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on +infinity");
6147638c70bSjruoho }
615d61c405bSriastradh ATF_TC_BODY(log2_inf, tc)
6167638c70bSjruoho {
6177638c70bSjruoho 
618d61c405bSriastradh 	if (!isinf(INFINITY))
619d61c405bSriastradh 		atf_tc_skip("no infinities on this architecture");
6207638c70bSjruoho 
621d61c405bSriastradh 	CHECK_EQ(0, log2f, INFINITY, INFINITY);
622d61c405bSriastradh 	CHECK_EQ(0, log2, INFINITY, INFINITY);
623d61c405bSriastradh 	CHECKL_EQ(0, log2l, INFINITY, INFINITY);
6247638c70bSjruoho }
6257638c70bSjruoho 
6267638c70bSjruoho /*
6277638c70bSjruoho  * log(3)
6287638c70bSjruoho  */
629d61c405bSriastradh 
630d61c405bSriastradh ATF_TC(log_invalid);
631d61c405bSriastradh ATF_TC_HEAD(log_invalid, tc)
6329273f704Sjruoho {
633d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log/f/l on invalid inputs");
634d61c405bSriastradh }
635d61c405bSriastradh ATF_TC_BODY(log_invalid, tc)
636d61c405bSriastradh {
637d61c405bSriastradh 	unsigned i;
638d61c405bSriastradh 
639d61c405bSriastradh 	for (i = 0; i < __arraycount(logf_invalid); i++) {
640d61c405bSriastradh 		CHECK_NAN(i, logf, logf_invalid[i]);
641d61c405bSriastradh 		CHECK_NAN(i, log, logf_invalid[i]);
642d61c405bSriastradh 		CHECKL_NAN(i, logl, logf_invalid[i]);
6439273f704Sjruoho 	}
6449273f704Sjruoho 
645d61c405bSriastradh 	for (i = 0; i < __arraycount(log_invalid); i++) {
646d61c405bSriastradh 		CHECK_NAN(i, log, log_invalid[i]);
647d61c405bSriastradh 		CHECKL_NAN(i, logl, log_invalid[i]);
6489273f704Sjruoho 	}
6499273f704Sjruoho 
650d61c405bSriastradh 	for (i = 0; i < __arraycount(logl_invalid); i++) {
651d61c405bSriastradh 		CHECKL_NAN(i, logl, logl_invalid[i]);
652d61c405bSriastradh 	}
653a63adaf8Sjruoho }
654a63adaf8Sjruoho 
655d61c405bSriastradh ATF_TC(log_zero);
656d61c405bSriastradh ATF_TC_HEAD(log_zero, tc)
657a63adaf8Sjruoho {
658d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log/f/l on zero");
659d61c405bSriastradh }
660d61c405bSriastradh ATF_TC_BODY(log_zero, tc)
661d61c405bSriastradh {
662a63adaf8Sjruoho 
663d61c405bSriastradh 	CHECK_EQ(0, logf, +0., -HUGE_VALF);
664d61c405bSriastradh 	CHECK_EQ(0, log, +0., -HUGE_VAL);
665d61c405bSriastradh 	CHECKL_EQ(0, logl, +0., -HUGE_VALL);
666d61c405bSriastradh 
667d61c405bSriastradh 	CHECK_EQ(1, logf, -0., -HUGE_VALF);
668d61c405bSriastradh 	CHECK_EQ(1, log, -0., -HUGE_VAL);
669d61c405bSriastradh 	CHECKL_EQ(1, logl, -0., -HUGE_VALL);
6707638c70bSjruoho }
6717638c70bSjruoho 
6722f3695baSriastradh ATF_TC(log_exact);
6732f3695baSriastradh ATF_TC_HEAD(log_exact, tc)
6747638c70bSjruoho {
6752f3695baSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log/f/l exact cases");
676d61c405bSriastradh }
6772f3695baSriastradh ATF_TC_BODY(log_exact, tc)
678d61c405bSriastradh {
679d61c405bSriastradh 
680d61c405bSriastradh 	CHECK_EQ(0, logf, 1, 0);
681d61c405bSriastradh 	CHECK_EQ(0, log, 1, 0);
682d61c405bSriastradh 	CHECKL_EQ(0, logl, 1, 0);
683d61c405bSriastradh 
684d61c405bSriastradh 	ATF_CHECK_EQ(signbit(logf(1)), 0);
685d61c405bSriastradh 	ATF_CHECK_EQ(signbit(log(1)), 0);
686d61c405bSriastradh 	ATF_CHECK_EQ(signbit(logl(1)), 0);
6872f3695baSriastradh }
688d61c405bSriastradh 
6892f3695baSriastradh ATF_TC(log_approx);
6902f3695baSriastradh ATF_TC_HEAD(log_approx, tc)
6912f3695baSriastradh {
6922f3695baSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log/f/l approximate cases");
6932f3695baSriastradh }
6942f3695baSriastradh ATF_TC_BODY(log_approx, tc)
6952f3695baSriastradh {
6962f3695baSriastradh 	volatile long double e =
6972f3695baSriastradh 	    2.7182818284590452353602874713526624977572470937L;
6982f3695baSriastradh 	volatile long double e2 =
6992f3695baSriastradh 	    7.3890560989306502272304274605750078131803155705519L;
7002f3695baSriastradh 	volatile long double log_2 =
7012f3695baSriastradh 	    0.69314718055994530941723212145817656807550013436025L;
7022f3695baSriastradh 	volatile long double log_10 =
7032f3695baSriastradh 	    2.30258509299404568401799145468436420760110148862875L;
7042f3695baSriastradh 
7052f3695baSriastradh 	ATF_CHECK_MSG(fabsf((logf(2) - log_2)/log_2) < 2*FLT_EPSILON,
7062f3695baSriastradh 	    "logf(2)=%a=%.8g expected %a=%.8g",
7072f3695baSriastradh 	    logf(2), logf(2), (float)log_2, (float)log_2);
7082f3695baSriastradh 	ATF_CHECK_MSG(fabs((log(2) - log_2)/log_2) < 2*DBL_EPSILON,
7092f3695baSriastradh 	    "log(2)=%a=%.17g expected %a=%.17g",
7102f3695baSriastradh 	    log(2), log(2), (double)log_2, (double)log_2);
7112f3695baSriastradh 	ATF_CHECK_MSG(fabsl((logl(2) - log_2)/log_2) < 2*LDBL_EPSILON,
7122f3695baSriastradh 	    "logl(2)=%La=%.34Lg expected %La=%.34Lg",
7132f3695baSriastradh 	    logl(2), logl(2), log_2, log_2);
7142f3695baSriastradh 
7152f3695baSriastradh 	ATF_CHECK_MSG(fabsf((logf(e) - 1)/1) < 2*FLT_EPSILON,
716d61c405bSriastradh 	    "logf(e)=%a=%.8g", logf(e), logf(e));
7172f3695baSriastradh 	ATF_CHECK_MSG(fabs((log(e) - 1)/1) < 2*DBL_EPSILON,
718d61c405bSriastradh 	    "log(e)=%a=%.17g", log(e), log(e));
7192f3695baSriastradh 	ATF_CHECK_MSG(fabsl((logl(e) - 1)/1) < 2*LDBL_EPSILON,
720d61c405bSriastradh 	    "logl(e)=%La=%.34Lg", logl(e), logl(e));
7212f3695baSriastradh 
7222f3695baSriastradh 	ATF_CHECK_MSG(fabsf((logf(e2) - 2)/2) < 2*FLT_EPSILON,
7232f3695baSriastradh 	    "logf(e)=%a=%.8g", logf(e2), logf(e2));
7242f3695baSriastradh 	ATF_CHECK_MSG(fabs((log(e2) - 2)/2) < 2*DBL_EPSILON,
7252f3695baSriastradh 	    "log(e)=%a=%.17g", log(e2), log(e2));
7262f3695baSriastradh 	ATF_CHECK_MSG(fabsl((logl(e2) - 2)/2) < 2*LDBL_EPSILON,
7272f3695baSriastradh 	    "logl(e)=%La=%.34Lg", logl(e2), logl(e2));
7282f3695baSriastradh 
7292f3695baSriastradh 	ATF_CHECK_MSG(fabsf((logf(10) - log_10)/log_10) < 2*FLT_EPSILON,
7302f3695baSriastradh 	    "logf(10)=%a=%.8g expected %a=%.8g",
7312f3695baSriastradh 	    logf(10), logf(10), (float)log_10, (float)log_10);
7322f3695baSriastradh 	ATF_CHECK_MSG(fabs((log(10) - log_10)/log_10) < 2*DBL_EPSILON,
7332f3695baSriastradh 	    "log(10)=%a=%.17g expected %a=%.17g",
7342f3695baSriastradh 	    log(10), log(10), (double)log_10, (double)log_10);
7352f3695baSriastradh 	ATF_CHECK_MSG(fabsl((logl(10) - log_10)/log_10) < 2*LDBL_EPSILON,
7362f3695baSriastradh 	    "logl(10)=%La=%.34Lg expected %La=%.34Lg",
7372f3695baSriastradh 	    logl(10), logl(10), log_10, log_10);
7387638c70bSjruoho }
7397638c70bSjruoho 
740d61c405bSriastradh ATF_TC(log_inf);
741d61c405bSriastradh ATF_TC_HEAD(log_inf, tc)
7427638c70bSjruoho {
743d61c405bSriastradh 	atf_tc_set_md_var(tc, "descr", "Test log/f/l on +infinity");
7447638c70bSjruoho }
745d61c405bSriastradh ATF_TC_BODY(log_inf, tc)
7467638c70bSjruoho {
7477638c70bSjruoho 
748d61c405bSriastradh 	if (!isinf(INFINITY))
749d61c405bSriastradh 		atf_tc_skip("no infinities on this architecture");
7507638c70bSjruoho 
751d61c405bSriastradh 	CHECK_EQ(0, logf, INFINITY, INFINITY);
752d61c405bSriastradh 	CHECK_EQ(0, log, INFINITY, INFINITY);
753d61c405bSriastradh 	CHECKL_EQ(0, logl, INFINITY, INFINITY);
754a63adaf8Sjruoho }
755a63adaf8Sjruoho 
756a63adaf8Sjruoho ATF_TP_ADD_TCS(tp)
757a63adaf8Sjruoho {
758a63adaf8Sjruoho 
759d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log10_invalid);
760d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log10_zero);
761d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log10_exact);
7622f3695baSriastradh 	ATF_TP_ADD_TC(tp, log10_approx);
763d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log10_inf);
7647638c70bSjruoho 
765d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log1p_invalid);
766d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log1p_neg_one);
767d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log1p_exact);
7682f3695baSriastradh 	ATF_TP_ADD_TC(tp, log1p_approx);
769d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log1p_inf);
7707638c70bSjruoho 
771d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log2_invalid);
772d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log2_zero);
773d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log2_exact);
7742f3695baSriastradh 	ATF_TP_ADD_TC(tp, log2_approx);
775d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log2_inf);
7767638c70bSjruoho 
777d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log_invalid);
778d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log_zero);
7792f3695baSriastradh 	ATF_TP_ADD_TC(tp, log_exact);
7802f3695baSriastradh 	ATF_TP_ADD_TC(tp, log_approx);
781d61c405bSriastradh 	ATF_TP_ADD_TC(tp, log_inf);
782a63adaf8Sjruoho 
783a63adaf8Sjruoho 	return atf_no_error();
784a63adaf8Sjruoho }
785