xref: /netbsd-src/tests/lib/libm/t_ldexp.c (revision a8a8e5f56ad4190e6012a1f1840e6e147c479a7a)
1*a8a8e5f5Sriastradh /* $NetBSD: t_ldexp.c,v 1.17 2018/11/07 03:59:36 riastradh Exp $ */
2e4094036Sjruoho 
3e4094036Sjruoho /*-
4e4094036Sjruoho  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5e4094036Sjruoho  * All rights reserved.
6e4094036Sjruoho  *
7e4094036Sjruoho  * This code is derived from software contributed to The NetBSD Foundation
8e4094036Sjruoho  * by Jukka Ruohonen.
9e4094036Sjruoho  *
10e4094036Sjruoho  * Redistribution and use in source and binary forms, with or without
11e4094036Sjruoho  * modification, are permitted provided that the following conditions
12e4094036Sjruoho  * are met:
13e4094036Sjruoho  * 1. Redistributions of source code must retain the above copyright
14e4094036Sjruoho  *    notice, this list of conditions and the following disclaimer.
15e4094036Sjruoho  * 2. Redistributions in binary form must reproduce the above copyright
16e4094036Sjruoho  *    notice, this list of conditions and the following disclaimer in the
17e4094036Sjruoho  *    documentation and/or other materials provided with the distribution.
18e4094036Sjruoho  *
19e4094036Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20e4094036Sjruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21e4094036Sjruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22e4094036Sjruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23e4094036Sjruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24e4094036Sjruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25e4094036Sjruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26e4094036Sjruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27e4094036Sjruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28e4094036Sjruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29e4094036Sjruoho  * POSSIBILITY OF SUCH DAMAGE.
30e4094036Sjruoho  */
31e4094036Sjruoho #include <sys/cdefs.h>
32*a8a8e5f5Sriastradh __RCSID("$NetBSD: t_ldexp.c,v 1.17 2018/11/07 03:59:36 riastradh Exp $");
33e110dcc9Sjmmv 
34e110dcc9Sjmmv #include <sys/param.h>
359ebeca8aSjruoho 
369ebeca8aSjruoho #include <atf-c.h>
37e4094036Sjruoho 
38*a8a8e5f5Sriastradh #include <float.h>
39e4094036Sjruoho #include <limits.h>
40*a8a8e5f5Sriastradh #include <math.h>
419ebeca8aSjruoho #include <stdio.h>
429ebeca8aSjruoho #include <string.h>
43e4094036Sjruoho 
449ebeca8aSjruoho #define SKIP	9999
459ebeca8aSjruoho #define FORMAT  "%23.23lg"
46e4094036Sjruoho 
47e4094036Sjruoho static const int exps[] = { 0, 1, -1, 100, -100 };
48e4094036Sjruoho 
499ebeca8aSjruoho struct ldexp_test {
509ebeca8aSjruoho 	double	    x;
519ebeca8aSjruoho 	int	    exp1;
529ebeca8aSjruoho 	int	    exp2;
539ebeca8aSjruoho 	const char *result;
549ebeca8aSjruoho };
559ebeca8aSjruoho 
569ebeca8aSjruoho struct ldexp_test ldexp_basic[] = {
579ebeca8aSjruoho 	{ 1.0,	5,	SKIP,	"                     32" },
589ebeca8aSjruoho 	{ 1.0,	1022,	SKIP,	"4.4942328371557897693233e+307" },
599ebeca8aSjruoho 	{ 1.0,	1023,	-1,	"4.4942328371557897693233e+307" },
609ebeca8aSjruoho 	{ 1.0,	1023,	SKIP,	"8.9884656743115795386465e+307" },
619ebeca8aSjruoho 	{ 1.0,	1022,	1,	"8.9884656743115795386465e+307" },
629ebeca8aSjruoho 	{ 1.0,	-1022,	2045,	"8.9884656743115795386465e+307" },
639ebeca8aSjruoho 	{ 1.0,	-5,	SKIP,	"                0.03125" },
649ebeca8aSjruoho 	{ 1.0,	-1021,	SKIP,	"4.4501477170144027661805e-308" },
659ebeca8aSjruoho 	{ 1.0,	-1022,	1,	"4.4501477170144027661805e-308" },
669ebeca8aSjruoho 	{ 1.0,	-1022,	SKIP,	"2.2250738585072013830902e-308" },
679ebeca8aSjruoho 	{ 1.0,	-1021,	-1,	"2.2250738585072013830902e-308" },
689ebeca8aSjruoho 	{ 1.0,	1023,	-2045,	"2.2250738585072013830902e-308" },
699ebeca8aSjruoho 	{ 1.0,	1023,	-1023,	"                      1" },
709ebeca8aSjruoho 	{ 1.0,	-1022,	1022,	"                      1" },
719ebeca8aSjruoho 	{ 0,	0,	0,	NULL }
729ebeca8aSjruoho };
739ebeca8aSjruoho 
749ebeca8aSjruoho struct ldexp_test ldexp_zero[] = {
759ebeca8aSjruoho 	{ 0.0,	-1,	SKIP,	"                      0" },
769ebeca8aSjruoho 	{ 0.0,	0,	SKIP,	"                      0" },
779ebeca8aSjruoho 	{ 0.0,	1,	SKIP,	"                      0" },
789ebeca8aSjruoho 	{ 0.0,	1024,	SKIP,	"                      0" },
799ebeca8aSjruoho 	{ 0.0,	1025,	SKIP,	"                      0" },
809ebeca8aSjruoho 	{ 0.0,	-1023,	SKIP,	"                      0" },
819ebeca8aSjruoho 	{ 0.0,	-1024,	SKIP,	"                      0" },
829ebeca8aSjruoho 	{ 0,	0,	0,	NULL }
839ebeca8aSjruoho };
849ebeca8aSjruoho 
859ebeca8aSjruoho struct ldexp_test ldexp_infinity[] = {
869ebeca8aSjruoho 	{ 1.0,	1024,	-1,	"                    inf" },
879ebeca8aSjruoho 	{ 1.0,	1024,	0,	"                    inf" },
889ebeca8aSjruoho 	{ 1.0,	1024,	1,	"                    inf" },
899ebeca8aSjruoho 	{ -1.0,	1024,	-1,	"                   -inf" },
909ebeca8aSjruoho 	{ -1.0,	1024,	0,	"                   -inf" },
919ebeca8aSjruoho 	{ -1.0,	1024,	1,	"                   -inf" },
929ebeca8aSjruoho 	{ 0,	0,	0,	NULL }
939ebeca8aSjruoho };
949ebeca8aSjruoho 
959ebeca8aSjruoho struct ldexp_test ldexp_overflow[] = {
969ebeca8aSjruoho 	{ 1.0,	1024,	SKIP,	"                    inf" },
979ebeca8aSjruoho 	{ 1.0,	1023,	1,	"                    inf" },
989ebeca8aSjruoho 	{ 1.0,	-1022,	2046,	"                    inf" },
999ebeca8aSjruoho 	{ 1.0,	1025,	SKIP,	"                    inf" },
1002b773534Smaya 	{ 2.0,	INT_MAX,SKIP,	"                    inf" },
1019ebeca8aSjruoho 	{ -1.0,	1024,	SKIP,	"                   -inf" },
1029ebeca8aSjruoho 	{ -1.0,	1023,	1,	"                   -inf" },
1039ebeca8aSjruoho 	{ -1.0,	-1022,	2046,	"                   -inf" },
1049ebeca8aSjruoho 	{ -1.0,	1025,	SKIP,	"                   -inf" },
1052b773534Smaya 	{ -2.0, INT_MAX,SKIP,	"                   -inf" },
1069ebeca8aSjruoho 	{ 0,	0,	0,	NULL }
1079ebeca8aSjruoho };
1089ebeca8aSjruoho 
1099ebeca8aSjruoho struct ldexp_test ldexp_denormal[] = {
1109ebeca8aSjruoho 	{ 1.0,	-1023,	SKIP,	"1.1125369292536006915451e-308" },
1119ebeca8aSjruoho 	{ 1.0,	-1022,	-1,	"1.1125369292536006915451e-308" },
1129ebeca8aSjruoho 	{ 1.0,	1023,	-2046,	"1.1125369292536006915451e-308" },
1139ebeca8aSjruoho 	{ 1.0,	-1024,	SKIP,	"5.5626846462680034577256e-309" },
1149ebeca8aSjruoho 	{ 1.0,	-1074,	SKIP,	"4.9406564584124654417657e-324" },
1159ebeca8aSjruoho 	{ -1.0,	-1023,	SKIP,	"-1.1125369292536006915451e-308" },
1169ebeca8aSjruoho 	{ -1.0,	-1022,	-1,	"-1.1125369292536006915451e-308" },
1179ebeca8aSjruoho 	{ -1.0,	1023,	-2046,	"-1.1125369292536006915451e-308" },
1189ebeca8aSjruoho 	{ -1.0,	-1024,	SKIP,	"-5.5626846462680034577256e-309" },
1199ebeca8aSjruoho 	{ -1.0,	-1074,	SKIP,	"-4.9406564584124654417657e-324" },
1209ebeca8aSjruoho 	{ 0,	0,	0,	NULL }
1219ebeca8aSjruoho };
1229ebeca8aSjruoho 
1239ebeca8aSjruoho struct ldexp_test ldexp_underflow[] = {
1249ebeca8aSjruoho 	{ 1.0,	-1075,	SKIP,	"                      0" },
1259ebeca8aSjruoho 	{ 1.0,	-1074,	-1,	"                      0" },
1269ebeca8aSjruoho 	{ 1.0,	1023,	-2098,	"                      0" },
1279ebeca8aSjruoho 	{ 1.0,	-1076,	SKIP,	"                      0" },
1289ebeca8aSjruoho 	{ -1.0,	-1075,	SKIP,	"                     -0" },
1299ebeca8aSjruoho 	{ -1.0,	-1074,	-1,	"                     -0" },
1309ebeca8aSjruoho 	{ -1.0,	1023,	-2098,	"                     -0" },
1319ebeca8aSjruoho 	{ -1.0,	-1076,	SKIP,	"                     -0" },
1329ebeca8aSjruoho 	{ 0,	0,	0,	NULL }
1339ebeca8aSjruoho };
1349ebeca8aSjruoho 
1359ebeca8aSjruoho struct ldexp_test ldexp_denormal_large[] = {
1369ebeca8aSjruoho 	{ 1.0,	-1028,	1024,	"                 0.0625" },
1379ebeca8aSjruoho 	{ 1.0,	-1028,	1025,	"                  0.125" },
1389ebeca8aSjruoho 	{ 1.0,	-1028,	1026,	"                   0.25" },
1399ebeca8aSjruoho 	{ 1.0,	-1028,	1027,	"                    0.5" },
1409ebeca8aSjruoho 	{ 1.0,	-1028,	1028,	"                      1" },
1419ebeca8aSjruoho 	{ 1.0,	-1028,	1029,	"                      2" },
1429ebeca8aSjruoho 	{ 1.0,	-1028,	1030,	"                      4" },
1439ebeca8aSjruoho 	{ 1.0,	-1028,	1040,	"                   4096" },
1449ebeca8aSjruoho 	{ 1.0,	-1028,	1050,	"                4194304" },
1459ebeca8aSjruoho 	{ 1.0,	-1028,	1060,	"             4294967296" },
1469ebeca8aSjruoho 	{ 1.0,	-1028,	1100,	" 4722366482869645213696" },
1479ebeca8aSjruoho 	{ 1.0,	-1028,	1200,	"5.9863107065073783529623e+51" },
1489ebeca8aSjruoho 	{ 1.0,	-1028,	1300,	"7.5885503602567541832791e+81" },
1499ebeca8aSjruoho 	{ 1.0,	-1028,	1400,	"9.6196304190416209014353e+111" },
1509ebeca8aSjruoho 	{ 1.0,	-1028,	1500,	"1.2194330274671844653834e+142" },
1519ebeca8aSjruoho 	{ 1.0,	-1028,	1600,	"1.5458150092069033378781e+172" },
1529ebeca8aSjruoho 	{ 1.0,	-1028,	1700,	"1.9595533242629369747791e+202" },
1539ebeca8aSjruoho 	{ 1.0,	-1028,	1800,	"2.4840289476811342962384e+232" },
1549ebeca8aSjruoho 	{ 1.0,	-1028,	1900,	"3.1488807865122869393369e+262" },
1559ebeca8aSjruoho 	{ 1.0,	-1028,	2000,	"3.9916806190694396233127e+292" },
1569ebeca8aSjruoho 	{ 1.0,	-1028,	2046,	"2.808895523222368605827e+306" },
1579ebeca8aSjruoho 	{ 1.0,	-1028,	2047,	"5.6177910464447372116541e+306" },
1589ebeca8aSjruoho 	{ 1.0,	-1028,	2048,	"1.1235582092889474423308e+307" },
1599ebeca8aSjruoho 	{ 1.0,	-1028,	2049,	"2.2471164185778948846616e+307" },
1609ebeca8aSjruoho 	{ 1.0,	-1028,	2050,	"4.4942328371557897693233e+307" },
1619ebeca8aSjruoho 	{ 1.0,	-1028,	2051,	"8.9884656743115795386465e+307" },
1629ebeca8aSjruoho 	{ 0,	0,	0,	NULL }
1639ebeca8aSjruoho };
1649ebeca8aSjruoho 
1659ebeca8aSjruoho static void
run_test(struct ldexp_test * table)1669ebeca8aSjruoho run_test(struct ldexp_test *table)
1679ebeca8aSjruoho {
1689ebeca8aSjruoho 	char outbuf[64];
1699ebeca8aSjruoho 	size_t i;
1709ebeca8aSjruoho 	double v;
1719ebeca8aSjruoho 
1729ebeca8aSjruoho 	for (i = 0; table->result != NULL; table++, i++) {
1739ebeca8aSjruoho 
1749ebeca8aSjruoho 		v = ldexp(table->x, table->exp1);
1759ebeca8aSjruoho 
176d63d1100Smaya 		if (table->exp2 != SKIP)
1779ebeca8aSjruoho 			v = ldexp(v, table->exp2);
1789ebeca8aSjruoho 
1799ebeca8aSjruoho 		(void)snprintf(outbuf, sizeof(outbuf), FORMAT, v);
1809ebeca8aSjruoho 
1819ebeca8aSjruoho 		ATF_CHECK_STREQ_MSG(table->result, outbuf,
1829ebeca8aSjruoho 			    "Entry %zu:\n\tExp: \"%s\"\n\tAct: \"%s\"",
1839ebeca8aSjruoho 			    i, table->result, outbuf);
1849ebeca8aSjruoho 	}
1859ebeca8aSjruoho }
1869ebeca8aSjruoho 
187e4094036Sjruoho /*
188e4094036Sjruoho  * ldexp(3)
189e4094036Sjruoho  */
19095fc86fcSjruoho ATF_TC(ldexp_exp2);
ATF_TC_HEAD(ldexp_exp2,tc)19195fc86fcSjruoho ATF_TC_HEAD(ldexp_exp2, tc)
19295fc86fcSjruoho {
19395fc86fcSjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexp(x, n) == x * exp2(n)");
19495fc86fcSjruoho }
19595fc86fcSjruoho 
ATF_TC_BODY(ldexp_exp2,tc)19695fc86fcSjruoho ATF_TC_BODY(ldexp_exp2, tc)
19795fc86fcSjruoho {
198ca5cfe71Sjruoho 	const double n[] = { 1, 2, 3, 10, 50, 100 };
199*a8a8e5f5Sriastradh 	const double eps = DBL_EPSILON;
2006ceed68fSjruoho 	const double x = 12.0;
20195fc86fcSjruoho 	size_t i;
20295fc86fcSjruoho 
20395fc86fcSjruoho 	for (i = 0; i < __arraycount(n); i++) {
204*a8a8e5f5Sriastradh 		double y = ldexp(x, n[i]);
2056ceed68fSjruoho 
206*a8a8e5f5Sriastradh 		if (!(fabs((y - (x * exp2(n[i])))/y) <= eps)) {
207*a8a8e5f5Sriastradh 			atf_tc_fail_nonfatal("ldexp(%.17g, %.17g) = %.17g "
208*a8a8e5f5Sriastradh 			    "!= %.17g * exp2(%.17g) = %.17g",
209*a8a8e5f5Sriastradh 			    x, n[i], y, x, n[i], (x * exp2(n[i])));
2106ceed68fSjruoho 		}
21195fc86fcSjruoho 	}
21295fc86fcSjruoho }
21395fc86fcSjruoho 
214e4094036Sjruoho ATF_TC(ldexp_nan);
ATF_TC_HEAD(ldexp_nan,tc)215e4094036Sjruoho ATF_TC_HEAD(ldexp_nan, tc)
216e4094036Sjruoho {
217f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexp(NaN) == NaN");
218e4094036Sjruoho }
219e4094036Sjruoho 
ATF_TC_BODY(ldexp_nan,tc)220e4094036Sjruoho ATF_TC_BODY(ldexp_nan, tc)
221e4094036Sjruoho {
222e4094036Sjruoho 	const double x = 0.0L / 0.0L;
223e4094036Sjruoho 	double y;
224e4094036Sjruoho 	size_t i;
225e4094036Sjruoho 
226173345a5Sjruoho 	ATF_REQUIRE(isnan(x) != 0);
227173345a5Sjruoho 
228e4094036Sjruoho 	for (i = 0; i < __arraycount(exps); i++) {
229e4094036Sjruoho 		y = ldexp(x, exps[i]);
230e4094036Sjruoho 		ATF_CHECK(isnan(y) != 0);
231e4094036Sjruoho 	}
232e4094036Sjruoho }
233e4094036Sjruoho 
234e4094036Sjruoho ATF_TC(ldexp_inf_neg);
ATF_TC_HEAD(ldexp_inf_neg,tc)235e4094036Sjruoho ATF_TC_HEAD(ldexp_inf_neg, tc)
236e4094036Sjruoho {
237f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexp(-Inf) == -Inf");
238e4094036Sjruoho }
239e4094036Sjruoho 
ATF_TC_BODY(ldexp_inf_neg,tc)240e4094036Sjruoho ATF_TC_BODY(ldexp_inf_neg, tc)
241e4094036Sjruoho {
242e4094036Sjruoho 	const double x = -1.0L / 0.0L;
243e4094036Sjruoho 	size_t i;
244e4094036Sjruoho 
245e4094036Sjruoho 	for (i = 0; i < __arraycount(exps); i++)
246e4094036Sjruoho 		ATF_CHECK(ldexp(x, exps[i]) == x);
247e4094036Sjruoho }
248e4094036Sjruoho 
249e4094036Sjruoho ATF_TC(ldexp_inf_pos);
ATF_TC_HEAD(ldexp_inf_pos,tc)250e4094036Sjruoho ATF_TC_HEAD(ldexp_inf_pos, tc)
251e4094036Sjruoho {
252f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexp(+Inf) == +Inf");
253e4094036Sjruoho }
254e4094036Sjruoho 
ATF_TC_BODY(ldexp_inf_pos,tc)255e4094036Sjruoho ATF_TC_BODY(ldexp_inf_pos, tc)
256e4094036Sjruoho {
257e4094036Sjruoho 	const double x = 1.0L / 0.0L;
258e4094036Sjruoho 	size_t i;
259e4094036Sjruoho 
260e4094036Sjruoho 	for (i = 0; i < __arraycount(exps); i++)
261e4094036Sjruoho 		ATF_CHECK(ldexp(x, exps[i]) == x);
262e4094036Sjruoho }
263e4094036Sjruoho 
264e4094036Sjruoho ATF_TC(ldexp_zero_neg);
ATF_TC_HEAD(ldexp_zero_neg,tc)265e4094036Sjruoho ATF_TC_HEAD(ldexp_zero_neg, tc)
266e4094036Sjruoho {
267f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexp(-0.0) == -0.0");
268e4094036Sjruoho }
269e4094036Sjruoho 
ATF_TC_BODY(ldexp_zero_neg,tc)270e4094036Sjruoho ATF_TC_BODY(ldexp_zero_neg, tc)
271e4094036Sjruoho {
272e4094036Sjruoho 	const double x = -0.0L;
273173345a5Sjruoho 	double y;
274e4094036Sjruoho 	size_t i;
275e4094036Sjruoho 
276173345a5Sjruoho 	ATF_REQUIRE(signbit(x) != 0);
277173345a5Sjruoho 
278173345a5Sjruoho 	for (i = 0; i < __arraycount(exps); i++) {
279173345a5Sjruoho 		y = ldexp(x, exps[i]);
280173345a5Sjruoho 		ATF_CHECK(x == y);
281173345a5Sjruoho 		ATF_CHECK(signbit(y) != 0);
282173345a5Sjruoho 	}
283e4094036Sjruoho }
284e4094036Sjruoho 
285e4094036Sjruoho ATF_TC(ldexp_zero_pos);
ATF_TC_HEAD(ldexp_zero_pos,tc)286e4094036Sjruoho ATF_TC_HEAD(ldexp_zero_pos, tc)
287e4094036Sjruoho {
288f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexp(+0.0) == +0.0");
289e4094036Sjruoho }
290e4094036Sjruoho 
ATF_TC_BODY(ldexp_zero_pos,tc)291e4094036Sjruoho ATF_TC_BODY(ldexp_zero_pos, tc)
292e4094036Sjruoho {
293e4094036Sjruoho 	const double x = 0.0L;
294173345a5Sjruoho 	double y;
295e4094036Sjruoho 	size_t i;
296e4094036Sjruoho 
297173345a5Sjruoho 	ATF_REQUIRE(signbit(x) == 0);
298173345a5Sjruoho 
299173345a5Sjruoho 	for (i = 0; i < __arraycount(exps); i++) {
300173345a5Sjruoho 		y = ldexp(x, exps[i]);
301173345a5Sjruoho 		ATF_CHECK(x == y);
302173345a5Sjruoho 		ATF_CHECK(signbit(y) == 0);
303173345a5Sjruoho 	}
304e4094036Sjruoho }
305e4094036Sjruoho 
3068c901a04Sjruoho /*
3078c901a04Sjruoho  * ldexpf(3)
3088c901a04Sjruoho  */
3098c901a04Sjruoho 
31095fc86fcSjruoho ATF_TC(ldexpf_exp2f);
ATF_TC_HEAD(ldexpf_exp2f,tc)31195fc86fcSjruoho ATF_TC_HEAD(ldexpf_exp2f, tc)
31295fc86fcSjruoho {
31395fc86fcSjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(x, n) == x * exp2f(n)");
31495fc86fcSjruoho }
31595fc86fcSjruoho 
ATF_TC_BODY(ldexpf_exp2f,tc)31695fc86fcSjruoho ATF_TC_BODY(ldexpf_exp2f, tc)
31795fc86fcSjruoho {
318ca5cfe71Sjruoho 	const float n[] = { 1, 2, 3, 10, 50, 100 };
319*a8a8e5f5Sriastradh 	const float eps = FLT_EPSILON;
320ca5cfe71Sjruoho 	const float x = 12.0;
32195fc86fcSjruoho 	size_t i;
32295fc86fcSjruoho 
32395fc86fcSjruoho 	for (i = 0; i < __arraycount(n); i++) {
324*a8a8e5f5Sriastradh 		float y = ldexpf(x, n[i]);
3256ceed68fSjruoho 
326*a8a8e5f5Sriastradh 		if (!(fabsf((y - (x * exp2f(n[i])))/y) <= eps)) {
327*a8a8e5f5Sriastradh 			atf_tc_fail_nonfatal("ldexpf(%.17g, %.17g) = %.17g "
328*a8a8e5f5Sriastradh 			    "!= %.17g * exp2f(%.17g) = %.17g",
329*a8a8e5f5Sriastradh 			    x, n[i], y, x, n[i], (x * exp2f(n[i])));
3306ceed68fSjruoho 		}
33195fc86fcSjruoho 	}
33295fc86fcSjruoho }
33395fc86fcSjruoho 
334e4094036Sjruoho ATF_TC(ldexpf_nan);
ATF_TC_HEAD(ldexpf_nan,tc)335e4094036Sjruoho ATF_TC_HEAD(ldexpf_nan, tc)
336e4094036Sjruoho {
337f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(NaN) == NaN");
338e4094036Sjruoho }
339e4094036Sjruoho 
ATF_TC_BODY(ldexpf_nan,tc)340e4094036Sjruoho ATF_TC_BODY(ldexpf_nan, tc)
341e4094036Sjruoho {
342e4094036Sjruoho 	const float x = 0.0L / 0.0L;
343e4094036Sjruoho 	float y;
344e4094036Sjruoho 	size_t i;
345e4094036Sjruoho 
346173345a5Sjruoho 	ATF_REQUIRE(isnan(x) != 0);
347173345a5Sjruoho 
348e4094036Sjruoho 	for (i = 0; i < __arraycount(exps); i++) {
349e4094036Sjruoho 		y = ldexpf(x, exps[i]);
350e4094036Sjruoho 		ATF_CHECK(isnan(y) != 0);
351e4094036Sjruoho 	}
352e4094036Sjruoho }
353e4094036Sjruoho 
354e4094036Sjruoho ATF_TC(ldexpf_inf_neg);
ATF_TC_HEAD(ldexpf_inf_neg,tc)355e4094036Sjruoho ATF_TC_HEAD(ldexpf_inf_neg, tc)
356e4094036Sjruoho {
357f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(-Inf) == -Inf");
358e4094036Sjruoho }
359e4094036Sjruoho 
ATF_TC_BODY(ldexpf_inf_neg,tc)360e4094036Sjruoho ATF_TC_BODY(ldexpf_inf_neg, tc)
361e4094036Sjruoho {
362e4094036Sjruoho 	const float x = -1.0L / 0.0L;
363e4094036Sjruoho 	size_t i;
364e4094036Sjruoho 
365e4094036Sjruoho 	for (i = 0; i < __arraycount(exps); i++)
366e4094036Sjruoho 		ATF_CHECK(ldexpf(x, exps[i]) == x);
367e4094036Sjruoho }
368e4094036Sjruoho 
369e4094036Sjruoho ATF_TC(ldexpf_inf_pos);
ATF_TC_HEAD(ldexpf_inf_pos,tc)370e4094036Sjruoho ATF_TC_HEAD(ldexpf_inf_pos, tc)
371e4094036Sjruoho {
372f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(+Inf) == +Inf");
373e4094036Sjruoho }
374e4094036Sjruoho 
ATF_TC_BODY(ldexpf_inf_pos,tc)375e4094036Sjruoho ATF_TC_BODY(ldexpf_inf_pos, tc)
376e4094036Sjruoho {
377e4094036Sjruoho 	const float x = 1.0L / 0.0L;
378e4094036Sjruoho 	size_t i;
379e4094036Sjruoho 
380e4094036Sjruoho 	for (i = 0; i < __arraycount(exps); i++)
381e4094036Sjruoho 		ATF_CHECK(ldexpf(x, exps[i]) == x);
382e4094036Sjruoho }
383e4094036Sjruoho 
384e4094036Sjruoho ATF_TC(ldexpf_zero_neg);
ATF_TC_HEAD(ldexpf_zero_neg,tc)385e4094036Sjruoho ATF_TC_HEAD(ldexpf_zero_neg, tc)
386e4094036Sjruoho {
387f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(-0.0) == -0.0");
388e4094036Sjruoho }
389e4094036Sjruoho 
ATF_TC_BODY(ldexpf_zero_neg,tc)390e4094036Sjruoho ATF_TC_BODY(ldexpf_zero_neg, tc)
391e4094036Sjruoho {
392e4094036Sjruoho 	const float x = -0.0L;
393173345a5Sjruoho 	float y;
394e4094036Sjruoho 	size_t i;
395e4094036Sjruoho 
396173345a5Sjruoho 	ATF_REQUIRE(signbit(x) != 0);
397173345a5Sjruoho 
398173345a5Sjruoho 	for (i = 0; i < __arraycount(exps); i++) {
399173345a5Sjruoho 		y = ldexpf(x, exps[i]);
400173345a5Sjruoho 		ATF_CHECK(x == y);
401173345a5Sjruoho 		ATF_CHECK(signbit(y) != 0);
402173345a5Sjruoho 	}
403e4094036Sjruoho }
404e4094036Sjruoho 
405e4094036Sjruoho ATF_TC(ldexpf_zero_pos);
ATF_TC_HEAD(ldexpf_zero_pos,tc)406e4094036Sjruoho ATF_TC_HEAD(ldexpf_zero_pos, tc)
407e4094036Sjruoho {
408f006ee10Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(+0.0) == +0.0");
409e4094036Sjruoho }
410e4094036Sjruoho 
ATF_TC_BODY(ldexpf_zero_pos,tc)411e4094036Sjruoho ATF_TC_BODY(ldexpf_zero_pos, tc)
412e4094036Sjruoho {
413e4094036Sjruoho 	const float x = 0.0L;
414173345a5Sjruoho 	float y;
415e4094036Sjruoho 	size_t i;
416e4094036Sjruoho 
417173345a5Sjruoho 	ATF_REQUIRE(signbit(x) == 0);
418173345a5Sjruoho 
419173345a5Sjruoho 	for (i = 0; i < __arraycount(exps); i++) {
420173345a5Sjruoho 		y = ldexpf(x, exps[i]);
421173345a5Sjruoho 		ATF_CHECK(x == y);
422173345a5Sjruoho 		ATF_CHECK(signbit(y) == 0);
423173345a5Sjruoho 	}
424e4094036Sjruoho }
425e4094036Sjruoho 
4269ebeca8aSjruoho #define TEST(name, desc)						\
4279ebeca8aSjruoho 	ATF_TC(name);							\
4289ebeca8aSjruoho 	ATF_TC_HEAD(name, tc)						\
4299ebeca8aSjruoho 	{								\
4309ebeca8aSjruoho 									\
4319ebeca8aSjruoho 		atf_tc_set_md_var(tc, "descr",				\
4329ebeca8aSjruoho 		    "Test ldexp(3) for " ___STRING(desc));		\
4339ebeca8aSjruoho 	}								\
4349ebeca8aSjruoho 	ATF_TC_BODY(name, tc)						\
4359ebeca8aSjruoho 	{								\
436e110dcc9Sjmmv 		if (strcmp("vax", MACHINE_ARCH) == 0)			\
437e110dcc9Sjmmv 			atf_tc_skip("Test not valid for " MACHINE_ARCH); \
4389ebeca8aSjruoho 		run_test(name);						\
4399ebeca8aSjruoho 	}
4409ebeca8aSjruoho 
TEST(ldexp_basic,basics)4419ebeca8aSjruoho TEST(ldexp_basic, basics)
4429ebeca8aSjruoho TEST(ldexp_zero, zero)
4439ebeca8aSjruoho TEST(ldexp_infinity, infinity)
4449ebeca8aSjruoho TEST(ldexp_overflow, overflow)
4459ebeca8aSjruoho TEST(ldexp_denormal, denormal)
4469ebeca8aSjruoho TEST(ldexp_denormal_large, large)
4479ebeca8aSjruoho TEST(ldexp_underflow, underflow)
4489ebeca8aSjruoho 
449e4094036Sjruoho ATF_TP_ADD_TCS(tp)
450e4094036Sjruoho {
451e4094036Sjruoho 
4529ebeca8aSjruoho 	ATF_TP_ADD_TC(tp, ldexp_basic);
4539ebeca8aSjruoho 	ATF_TP_ADD_TC(tp, ldexp_zero);
4549ebeca8aSjruoho 	ATF_TP_ADD_TC(tp, ldexp_infinity);
4559ebeca8aSjruoho 	ATF_TP_ADD_TC(tp, ldexp_overflow);
4569ebeca8aSjruoho 	ATF_TP_ADD_TC(tp, ldexp_denormal);
4579ebeca8aSjruoho 	ATF_TP_ADD_TC(tp, ldexp_underflow);
4589ebeca8aSjruoho 	ATF_TP_ADD_TC(tp, ldexp_denormal_large);
4599ebeca8aSjruoho 
46095fc86fcSjruoho 	ATF_TP_ADD_TC(tp, ldexp_exp2);
461e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexp_nan);
462e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexp_inf_neg);
463e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexp_inf_pos);
464e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexp_zero_neg);
465e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexp_zero_pos);
466e4094036Sjruoho 
46795fc86fcSjruoho 	ATF_TP_ADD_TC(tp, ldexpf_exp2f);
468e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexpf_nan);
469e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexpf_inf_neg);
470e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexpf_inf_pos);
471e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexpf_zero_neg);
472e4094036Sjruoho 	ATF_TP_ADD_TC(tp, ldexpf_zero_pos);
473e4094036Sjruoho 
474e4094036Sjruoho 	return atf_no_error();
475e4094036Sjruoho }
476