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