xref: /netbsd-src/tests/lib/libm/t_log.c (revision d61c405bebe521991ea8bb553a58d1abbc33e2fd)
1 /* $NetBSD: t_log.c,v 1.16 2024/07/15 06:19:17 riastradh Exp $ */
2 
3 /*-
4  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jukka Ruohonen.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: t_log.c,v 1.16 2024/07/15 06:19:17 riastradh Exp $");
33 
34 #include <atf-c.h>
35 
36 #include <errno.h>
37 #include <float.h>
38 #include <math.h>
39 #include <stdio.h>
40 #include <string.h>
41 
42 #define	CHECK_EQ(i, f, x, y)						      \
43 	ATF_CHECK_EQ_MSG(f(x), y,					      \
44 	    "[%u] %s(%a=%.17g)=%a=%.17g, expected %a=%.17g",		      \
45 	    (i), #f, (double)(x), (double)(x), f(x), f(x),		      \
46 	    (double)(y), (double)(y))
47 
48 #define	CHECKL_EQ(i, f, x, y)						      \
49 	ATF_CHECK_EQ_MSG(f(x), y,					      \
50 	    "[%u] %s(%La=%.17Lg)=%La=%.17Lg, expected %La=%.17Lg",	      \
51 	    (i), #f, (long double)(x), (long double)(x), f(x), f(x),	      \
52 	    (long double)(y), (long double)(y))
53 
54 #ifdef NAN
55 
56 #define	CHECK_NAN(i, f, x)						      \
57 	ATF_CHECK_MSG(isnan(f(x)),					      \
58 	    "[%u] %s(%a=%.17g)=%a=%.17g, expected NaN",			      \
59 	    (i), #f, (x), (x), f(x), f(x))
60 
61 #define	CHECKL_NAN(i, f, x)						      \
62 	ATF_CHECK_MSG(isnan(f(x)),					      \
63 	    "[%u] %s(%La=%.17Lg)=%La=%.17Lg, expected NaN",		      \
64 	    (i), #f, (long double)(x), (long double)(x), f(x), f(x))
65 
66 #else  /* !defined(NAN) */
67 
68 #define	CHECK_NAN(i, f, x) do						      \
69 {									      \
70 	int _checknan_error;						      \
71 	double _checknan_result;					      \
72 	errno = 0;							      \
73 	_checknan_result = f(x);					      \
74 	_checknan_error = errno;					      \
75 	ATF_CHECK_EQ_MSG(errno, EDOM,					      \
76 	    "[%u] %s(%a=%.17g)=%a=%.17g errno=%d, expected EDOM=%d",	      \
77 	    (i), #f, (double)(x), (double)(x),				      \
78 	    _checknan_result, _checknan_result,				      \
79 	    _checknan_error, EDOM);					      \
80 } while (0)
81 
82 #define	CHECKL_NAN(i, f, x) do						      \
83 {									      \
84 	int _checknan_error;						      \
85 	long double _checknan_result;					      \
86 	errno = 0;							      \
87 	_checknan_result = f(x);					      \
88 	_checknan_error = errno;					      \
89 	ATF_CHECK_EQ_MSG(errno, EDOM,					      \
90 	    "[%u] %s(%La=%.17Lg)=%La=%.17Lg errno=%d, expected EDOM=%d",      \
91 	    (i), #f, (long double)(x), (long double)(x),		      \
92 	    _checknan_result, _checknan_result,				      \
93 	    _checknan_error, EDOM);					      \
94 } while (0)
95 
96 #endif	/* NAN */
97 
98 static const float logf_invalid[] = {
99 #ifdef NAN
100 	NAN,
101 #endif
102 	-HUGE_VALF,
103 	-FLT_MAX,
104 	-10,
105 	-1,
106 	-FLT_EPSILON,
107 	-FLT_MIN,
108 #ifdef FLT_DENORM_MIN
109 	-FLT_DENORM_MIN,
110 #endif
111 };
112 
113 static const double log_invalid[] = {
114 #ifdef NAN
115 	NAN,
116 #endif
117 	-HUGE_VAL,
118 	-DBL_MAX,
119 	-10,
120 	-1,
121 	-DBL_EPSILON,
122 	-DBL_MIN,
123 #ifdef DBL_DENORM_MIN
124 	-DBL_DENORM_MIN,
125 #endif
126 };
127 
128 static const long double logl_invalid[] = {
129 #ifdef NAN
130 	NAN,
131 #endif
132 	-HUGE_VALL,
133 	-LDBL_MAX,
134 	-10,
135 	-1,
136 	-LDBL_EPSILON,
137 	-LDBL_MIN,
138 #ifdef LDBL_DENORM_MIN
139 	-LDBL_DENORM_MIN,
140 #endif
141 };
142 
143 static const float log1pf_invalid[] = {
144 #ifdef NAN
145 	NAN,
146 #endif
147 	-HUGE_VALF,
148 	-FLT_MAX,
149 	-10,
150 	-1 - FLT_EPSILON,
151 };
152 
153 static const double log1p_invalid[] = {
154 #ifdef NAN
155 	NAN,
156 #endif
157 	-HUGE_VAL,
158 	-DBL_MAX,
159 	-10,
160 	-1 - DBL_EPSILON,
161 };
162 
163 static const long double log1pl_invalid[] = {
164 #ifdef NAN
165 	NAN,
166 #endif
167 	-HUGE_VALL,
168 	-LDBL_MAX,
169 	-10,
170 	-1 - LDBL_EPSILON,
171 };
172 
173 /*
174  * log10(3)
175  */
176 static const struct {
177 	float x, y;
178 } log10f_exact[] = {
179 	{ 1, 0 },
180 	{ 10, 1 },
181 	{ 100, 2 },
182 };
183 
184 ATF_TC(log10_invalid);
185 ATF_TC_HEAD(log10_invalid, tc)
186 {
187 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on invalid inputs");
188 }
189 ATF_TC_BODY(log10_invalid, tc)
190 {
191 	unsigned i;
192 
193 	for (i = 0; i < __arraycount(logf_invalid); i++) {
194 		CHECK_NAN(i, log10f, logf_invalid[i]);
195 		CHECK_NAN(i, log10, logf_invalid[i]);
196 		CHECKL_NAN(i, log10l, logf_invalid[i]);
197 	}
198 
199 	for (i = 0; i < __arraycount(log_invalid); i++) {
200 		CHECK_NAN(i, log10, log_invalid[i]);
201 		CHECKL_NAN(i, log10l, log_invalid[i]);
202 	}
203 
204 	for (i = 0; i < __arraycount(logl_invalid); i++) {
205 		CHECKL_NAN(i, log10l, logl_invalid[i]);
206 	}
207 }
208 
209 ATF_TC(log10_zero);
210 ATF_TC_HEAD(log10_zero, tc)
211 {
212 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on zero");
213 }
214 ATF_TC_BODY(log10_zero, tc)
215 {
216 
217 	CHECK_EQ(0, log10f, +0., -HUGE_VALF);
218 	CHECK_EQ(0, log10, +0., -HUGE_VAL);
219 	CHECKL_EQ(0, log10l, +0., -HUGE_VALL);
220 
221 	CHECK_EQ(1, log10f, -0., -HUGE_VALF);
222 	CHECK_EQ(1, log10, -0., -HUGE_VAL);
223 	CHECKL_EQ(1, log10l, -0., -HUGE_VALL);
224 }
225 
226 ATF_TC(log10_exact);
227 ATF_TC_HEAD(log10_exact, tc)
228 {
229 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l exact cases");
230 }
231 ATF_TC_BODY(log10_exact, tc)
232 {
233 	unsigned i;
234 
235 	ATF_CHECK_EQ(signbit(log10f(1)), 0);
236 	ATF_CHECK_EQ(signbit(log10(1)), 0);
237 	ATF_CHECK_EQ(signbit(log10l(1)), 0);
238 
239 	for (i = 0; i < __arraycount(log10f_exact); i++) {
240 		const float x = log10f_exact[i].x;
241 		const float y = log10f_exact[i].y;
242 
243 		CHECK_EQ(i, log10f, x, y);
244 		CHECK_EQ(i, log10, x, y);
245 		CHECKL_EQ(i, log10l, x, y);
246 	}
247 }
248 
249 ATF_TC(log10_inf);
250 ATF_TC_HEAD(log10_inf, tc)
251 {
252 	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on +infinity");
253 }
254 ATF_TC_BODY(log10_inf, tc)
255 {
256 
257 	if (!isinf(INFINITY))
258 		atf_tc_skip("no infinities on this architecture");
259 
260 	CHECK_EQ(0, log10f, INFINITY, INFINITY);
261 	CHECK_EQ(0, log10, INFINITY, INFINITY);
262 	CHECKL_EQ(0, log10l, INFINITY, INFINITY);
263 }
264 
265 /*
266  * log1p(3)
267  */
268 
269 ATF_TC(log1p_invalid);
270 ATF_TC_HEAD(log1p_invalid, tc)
271 {
272 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on invalid inputs");
273 }
274 ATF_TC_BODY(log1p_invalid, tc)
275 {
276 	unsigned i;
277 
278 	for (i = 0; i < __arraycount(log1pf_invalid); i++) {
279 		CHECK_NAN(i, log1pf, log1pf_invalid[i]);
280 		CHECK_NAN(i, log1p, log1pf_invalid[i]);
281 		CHECKL_NAN(i, log1pl, log1pf_invalid[i]);
282 	}
283 
284 	for (i = 0; i < __arraycount(log1p_invalid); i++) {
285 		CHECK_NAN(i, log1p, log1p_invalid[i]);
286 		CHECKL_NAN(i, log1pl, log1p_invalid[i]);
287 	}
288 
289 	for (i = 0; i < __arraycount(log1pl_invalid); i++) {
290 		CHECKL_NAN(i, log1pl, log1pl_invalid[i]);
291 	}
292 }
293 
294 ATF_TC(log1p_neg_one);
295 ATF_TC_HEAD(log1p_neg_one, tc)
296 {
297 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on -1");
298 }
299 ATF_TC_BODY(log1p_neg_one, tc)
300 {
301 
302 	CHECK_EQ(0, log1pf, -1., -HUGE_VALF);
303 	CHECK_EQ(0, log1p, -1., -HUGE_VAL);
304 	CHECKL_EQ(0, log1pl, -1., -HUGE_VALL);
305 }
306 
307 ATF_TC(log1p_exact);
308 ATF_TC_HEAD(log1p_exact, tc)
309 {
310 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l exact cases");
311 }
312 ATF_TC_BODY(log1p_exact, tc)
313 {
314 
315 	/*
316 	 * Not _exact_, but the approximation is good enough.
317 	 */
318 #ifdef FLT_DENORM_MIN
319 	CHECK_EQ(0, log1pf, -FLT_DENORM_MIN, -FLT_DENORM_MIN);
320 #endif
321 #ifdef DBL_DENORM_MIN
322 	CHECK_EQ(0, log1p, -DBL_DENORM_MIN, -DBL_DENORM_MIN);
323 #endif
324 #ifdef LDBL_DENORM_MIN
325 	CHECKL_EQ(0, log1pl, -LDBL_DENORM_MIN, -LDBL_DENORM_MIN);
326 #endif
327 
328 	CHECK_EQ(1, log1pf, -FLT_MIN, -FLT_MIN);
329 	CHECK_EQ(1, log1p, -DBL_MIN, -DBL_MIN);
330 	CHECKL_EQ(1, log1pl, -LDBL_MIN, -LDBL_MIN);
331 
332 	CHECK_EQ(0, log1pf, -0., 0);
333 	CHECK_EQ(0, log1p, -0., 0);
334 	CHECKL_EQ(0, log1pl, -0., 0);
335 
336 	CHECK_EQ(1, log1pf, +0., 0);
337 	CHECK_EQ(1, log1p, +0., 0);
338 	CHECKL_EQ(1, log1pl, +0., 0);
339 
340 	CHECK_EQ(2, log1pf, 1, logf(2));
341 	CHECK_EQ(2, log1p, 1, log(2));
342 	CHECKL_EQ(2, log1pl, 1, logl(2));
343 }
344 
345 ATF_TC(log1p_inf);
346 ATF_TC_HEAD(log1p_inf, tc)
347 {
348 	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on +infinity");
349 }
350 ATF_TC_BODY(log1p_inf, tc)
351 {
352 
353 	if (!isinf(INFINITY))
354 		atf_tc_skip("no infinities on this architecture");
355 
356 	CHECK_EQ(0, log1pf, INFINITY, INFINITY);
357 	CHECK_EQ(0, log1p, INFINITY, INFINITY);
358 	CHECKL_EQ(0, log1pl, INFINITY, INFINITY);
359 }
360 
361 /*
362  * log2(3)
363  */
364 static const struct {
365 	float x, y;
366 } log2f_exact[] = {
367 #ifdef FLT_DENORM_MIN
368 	{ FLT_DENORM_MIN, FLT_MIN_EXP - FLT_MANT_DIG },
369 #endif
370 	{ FLT_MIN, FLT_MIN_EXP - 1 },
371 	{ 0.25, -2 },
372 	{ 0.5, -1 },
373 	{ 1, 0 },
374 	{ 2, 1 },
375 	{ 4, 2 },
376 	{ 8, 3 },
377 	{ 1 << FLT_MANT_DIG, FLT_MANT_DIG },
378 	{ (float)(1 << FLT_MANT_DIG) * (1 << FLT_MANT_DIG),
379 	  2*FLT_MANT_DIG },
380 };
381 static const struct {
382 	double x, y;
383 } log2_exact[] = {
384 #ifdef DBL_DENORM_MIN
385 	{ DBL_DENORM_MIN, DBL_MIN_EXP - DBL_MANT_DIG },
386 #endif
387 	{ DBL_MIN, DBL_MIN_EXP - 1 },
388 	{ (uint64_t)1 << DBL_MANT_DIG, DBL_MANT_DIG },
389 	{ ((double)((uint64_t)1 << DBL_MANT_DIG) *
390 		    ((uint64_t)1 << DBL_MANT_DIG)),
391 	  2*DBL_MANT_DIG },
392 };
393 
394 static const struct {
395 	long double x, y;
396 } log2l_exact[] = {
397 #ifdef LDBL_DENORM_MIN
398 	{ LDBL_DENORM_MIN, LDBL_MIN_EXP - LDBL_MANT_DIG },
399 #endif
400 	{ LDBL_MIN, LDBL_MIN_EXP - 1 },
401 	{ ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
402 		    ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))),
403 	  LDBL_MANT_DIG },
404 	{ (((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
405 			((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))) *
406 		    ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
407 			((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2)))),
408 	  2*LDBL_MANT_DIG },
409 };
410 
411 ATF_TC(log2_invalid);
412 ATF_TC_HEAD(log2_invalid, tc)
413 {
414 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on invalid inputs");
415 }
416 ATF_TC_BODY(log2_invalid, tc)
417 {
418 	unsigned i;
419 
420 	for (i = 0; i < __arraycount(logf_invalid); i++) {
421 		CHECK_NAN(i, log2f, logf_invalid[i]);
422 		CHECK_NAN(i, log2, logf_invalid[i]);
423 		CHECKL_NAN(i, log2l, logf_invalid[i]);
424 	}
425 
426 	for (i = 0; i < __arraycount(log_invalid); i++) {
427 		CHECK_NAN(i, log2, log_invalid[i]);
428 		CHECKL_NAN(i, log2l, log_invalid[i]);
429 	}
430 
431 	for (i = 0; i < __arraycount(logl_invalid); i++) {
432 		CHECKL_NAN(i, log2l, logl_invalid[i]);
433 	}
434 }
435 
436 ATF_TC(log2_zero);
437 ATF_TC_HEAD(log2_zero, tc)
438 {
439 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on zero");
440 }
441 ATF_TC_BODY(log2_zero, tc)
442 {
443 
444 	CHECK_EQ(0, log2f, +0., -HUGE_VALF);
445 	CHECK_EQ(0, log2, +0., -HUGE_VAL);
446 	CHECKL_EQ(0, log2l, +0., -HUGE_VALL);
447 
448 	CHECK_EQ(1, log2f, -0., -HUGE_VALF);
449 	CHECK_EQ(1, log2, -0., -HUGE_VAL);
450 	CHECKL_EQ(1, log2l, -0., -HUGE_VALL);
451 }
452 
453 ATF_TC(log2_exact);
454 ATF_TC_HEAD(log2_exact, tc)
455 {
456 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l exact cases");
457 }
458 ATF_TC_BODY(log2_exact, tc)
459 {
460 	unsigned i;
461 
462 	ATF_CHECK_EQ(signbit(log2f(1)), 0);
463 	ATF_CHECK_EQ(signbit(log2(1)), 0);
464 	ATF_CHECK_EQ(signbit(log2l(1)), 0);
465 
466 	for (i = 0; i < __arraycount(log2f_exact); i++) {
467 		const float x = log2f_exact[i].x;
468 		const float y = log2f_exact[i].y;
469 
470 		CHECK_EQ(i, log2f, x, y);
471 		CHECK_EQ(i, log2, x, y);
472 		CHECKL_EQ(i, log2l, x, y);
473 	}
474 
475 	for (i = 0; i < __arraycount(log2_exact); i++) {
476 		const double x = log2_exact[i].x;
477 		const double y = log2_exact[i].y;
478 
479 		CHECK_EQ(i, log2, x, y);
480 		CHECKL_EQ(i, log2l, x, y);
481 	}
482 
483 	for (i = 0; i < __arraycount(log2l_exact); i++) {
484 		const long double x = log2l_exact[i].x;
485 		const long double y = log2l_exact[i].y;
486 
487 		CHECKL_EQ(i, log2l, x, y);
488 	}
489 }
490 
491 ATF_TC(log2_inf);
492 ATF_TC_HEAD(log2_inf, tc)
493 {
494 	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on +infinity");
495 }
496 ATF_TC_BODY(log2_inf, tc)
497 {
498 
499 	if (!isinf(INFINITY))
500 		atf_tc_skip("no infinities on this architecture");
501 
502 	CHECK_EQ(0, log2f, INFINITY, INFINITY);
503 	CHECK_EQ(0, log2, INFINITY, INFINITY);
504 	CHECKL_EQ(0, log2l, INFINITY, INFINITY);
505 }
506 
507 /*
508  * log(3)
509  */
510 
511 ATF_TC(log_invalid);
512 ATF_TC_HEAD(log_invalid, tc)
513 {
514 	atf_tc_set_md_var(tc, "descr", "Test log/f/l on invalid inputs");
515 }
516 ATF_TC_BODY(log_invalid, tc)
517 {
518 	unsigned i;
519 
520 	for (i = 0; i < __arraycount(logf_invalid); i++) {
521 		CHECK_NAN(i, logf, logf_invalid[i]);
522 		CHECK_NAN(i, log, logf_invalid[i]);
523 		CHECKL_NAN(i, logl, logf_invalid[i]);
524 	}
525 
526 	for (i = 0; i < __arraycount(log_invalid); i++) {
527 		CHECK_NAN(i, log, log_invalid[i]);
528 		CHECKL_NAN(i, logl, log_invalid[i]);
529 	}
530 
531 	for (i = 0; i < __arraycount(logl_invalid); i++) {
532 		CHECKL_NAN(i, logl, logl_invalid[i]);
533 	}
534 }
535 
536 ATF_TC(log_zero);
537 ATF_TC_HEAD(log_zero, tc)
538 {
539 	atf_tc_set_md_var(tc, "descr", "Test log/f/l on zero");
540 }
541 ATF_TC_BODY(log_zero, tc)
542 {
543 
544 	CHECK_EQ(0, logf, +0., -HUGE_VALF);
545 	CHECK_EQ(0, log, +0., -HUGE_VAL);
546 	CHECKL_EQ(0, logl, +0., -HUGE_VALL);
547 
548 	CHECK_EQ(1, logf, -0., -HUGE_VALF);
549 	CHECK_EQ(1, log, -0., -HUGE_VAL);
550 	CHECKL_EQ(1, logl, -0., -HUGE_VALL);
551 }
552 
553 ATF_TC(log_normal);
554 ATF_TC_HEAD(log_normal, tc)
555 {
556 	atf_tc_set_md_var(tc, "descr", "Test log/f/l normal cases");
557 }
558 ATF_TC_BODY(log_normal, tc)
559 {
560 	volatile long double e = M_E;
561 
562 	CHECK_EQ(0, logf, 1, 0);
563 	CHECK_EQ(0, log, 1, 0);
564 	CHECKL_EQ(0, logl, 1, 0);
565 
566 	ATF_CHECK_EQ(signbit(logf(1)), 0);
567 	ATF_CHECK_EQ(signbit(log(1)), 0);
568 	ATF_CHECK_EQ(signbit(logl(1)), 0);
569 
570 	ATF_CHECK_MSG(fabsf((logf(e) - 1)/1) < FLT_EPSILON,
571 	    "logf(e)=%a=%.8g", logf(e), logf(e));
572 	ATF_CHECK_MSG(fabs((log(e) - 1)/1) < DBL_EPSILON,
573 	    "log(e)=%a=%.17g", log(e), log(e));
574 	ATF_CHECK_MSG(fabsl((logl(e) - 1)/1) < LDBL_EPSILON,
575 	    "logl(e)=%La=%.34Lg", logl(e), logl(e));
576 }
577 
578 ATF_TC(log_inf);
579 ATF_TC_HEAD(log_inf, tc)
580 {
581 	atf_tc_set_md_var(tc, "descr", "Test log/f/l on +infinity");
582 }
583 ATF_TC_BODY(log_inf, tc)
584 {
585 
586 	if (!isinf(INFINITY))
587 		atf_tc_skip("no infinities on this architecture");
588 
589 	CHECK_EQ(0, logf, INFINITY, INFINITY);
590 	CHECK_EQ(0, log, INFINITY, INFINITY);
591 	CHECKL_EQ(0, logl, INFINITY, INFINITY);
592 }
593 
594 ATF_TP_ADD_TCS(tp)
595 {
596 
597 	ATF_TP_ADD_TC(tp, log10_invalid);
598 	ATF_TP_ADD_TC(tp, log10_zero);
599 	ATF_TP_ADD_TC(tp, log10_exact);
600 	ATF_TP_ADD_TC(tp, log10_inf);
601 
602 	ATF_TP_ADD_TC(tp, log1p_invalid);
603 	ATF_TP_ADD_TC(tp, log1p_neg_one);
604 	ATF_TP_ADD_TC(tp, log1p_exact);
605 	ATF_TP_ADD_TC(tp, log1p_inf);
606 
607 	ATF_TP_ADD_TC(tp, log2_invalid);
608 	ATF_TP_ADD_TC(tp, log2_zero);
609 	ATF_TP_ADD_TC(tp, log2_exact);
610 	ATF_TP_ADD_TC(tp, log2_inf);
611 
612 	ATF_TP_ADD_TC(tp, log_invalid);
613 	ATF_TP_ADD_TC(tp, log_zero);
614 	ATF_TP_ADD_TC(tp, log_normal);
615 	ATF_TP_ADD_TC(tp, log_inf);
616 
617 	return atf_no_error();
618 }
619