xref: /freebsd-src/contrib/netbsd-tests/lib/libm/t_ldexp.c (revision 57718be8fa0bd5edc11ab9a72e68cc71982939a6)
1*57718be8SEnji Cooper /* $NetBSD: t_ldexp.c,v 1.13 2014/03/12 21:40:07 martin Exp $ */
2*57718be8SEnji Cooper 
3*57718be8SEnji Cooper /*-
4*57718be8SEnji Cooper  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5*57718be8SEnji Cooper  * All rights reserved.
6*57718be8SEnji Cooper  *
7*57718be8SEnji Cooper  * This code is derived from software contributed to The NetBSD Foundation
8*57718be8SEnji Cooper  * by Jukka Ruohonen.
9*57718be8SEnji Cooper  *
10*57718be8SEnji Cooper  * Redistribution and use in source and binary forms, with or without
11*57718be8SEnji Cooper  * modification, are permitted provided that the following conditions
12*57718be8SEnji Cooper  * are met:
13*57718be8SEnji Cooper  * 1. Redistributions of source code must retain the above copyright
14*57718be8SEnji Cooper  *    notice, this list of conditions and the following disclaimer.
15*57718be8SEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
16*57718be8SEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
17*57718be8SEnji Cooper  *    documentation and/or other materials provided with the distribution.
18*57718be8SEnji Cooper  *
19*57718be8SEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*57718be8SEnji Cooper  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*57718be8SEnji Cooper  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*57718be8SEnji Cooper  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*57718be8SEnji Cooper  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*57718be8SEnji Cooper  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*57718be8SEnji Cooper  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*57718be8SEnji Cooper  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*57718be8SEnji Cooper  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*57718be8SEnji Cooper  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*57718be8SEnji Cooper  * POSSIBILITY OF SUCH DAMAGE.
30*57718be8SEnji Cooper  */
31*57718be8SEnji Cooper #include <sys/cdefs.h>
32*57718be8SEnji Cooper __RCSID("$NetBSD: t_ldexp.c,v 1.13 2014/03/12 21:40:07 martin Exp $");
33*57718be8SEnji Cooper 
34*57718be8SEnji Cooper #include <sys/param.h>
35*57718be8SEnji Cooper 
36*57718be8SEnji Cooper #include <atf-c.h>
37*57718be8SEnji Cooper #include <atf-c/config.h>
38*57718be8SEnji Cooper 
39*57718be8SEnji Cooper #include <math.h>
40*57718be8SEnji Cooper #include <limits.h>
41*57718be8SEnji Cooper #include <stdio.h>
42*57718be8SEnji Cooper #include <string.h>
43*57718be8SEnji Cooper 
44*57718be8SEnji Cooper #define SKIP	9999
45*57718be8SEnji Cooper #define FORMAT  "%23.23lg"
46*57718be8SEnji Cooper 
47*57718be8SEnji Cooper static const int exps[] = { 0, 1, -1, 100, -100 };
48*57718be8SEnji Cooper 
49*57718be8SEnji Cooper struct ldexp_test {
50*57718be8SEnji Cooper 	double	    x;
51*57718be8SEnji Cooper 	int	    exp1;
52*57718be8SEnji Cooper 	int	    exp2;
53*57718be8SEnji Cooper 	const char *result;
54*57718be8SEnji Cooper };
55*57718be8SEnji Cooper 
56*57718be8SEnji Cooper struct ldexp_test ldexp_basic[] = {
57*57718be8SEnji Cooper 	{ 1.0,	5,	SKIP,	"                     32" },
58*57718be8SEnji Cooper 	{ 1.0,	1022,	SKIP,	"4.4942328371557897693233e+307" },
59*57718be8SEnji Cooper 	{ 1.0,	1023,	-1,	"4.4942328371557897693233e+307" },
60*57718be8SEnji Cooper 	{ 1.0,	1023,	SKIP,	"8.9884656743115795386465e+307" },
61*57718be8SEnji Cooper 	{ 1.0,	1022,	1,	"8.9884656743115795386465e+307" },
62*57718be8SEnji Cooper 	{ 1.0,	-1022,	2045,	"8.9884656743115795386465e+307" },
63*57718be8SEnji Cooper 	{ 1.0,	-5,	SKIP,	"                0.03125" },
64*57718be8SEnji Cooper 	{ 1.0,	-1021,	SKIP,	"4.4501477170144027661805e-308" },
65*57718be8SEnji Cooper 	{ 1.0,	-1022,	1,	"4.4501477170144027661805e-308" },
66*57718be8SEnji Cooper 	{ 1.0,	-1022,	SKIP,	"2.2250738585072013830902e-308" },
67*57718be8SEnji Cooper 	{ 1.0,	-1021,	-1,	"2.2250738585072013830902e-308" },
68*57718be8SEnji Cooper 	{ 1.0,	1023,	-2045,	"2.2250738585072013830902e-308" },
69*57718be8SEnji Cooper 	{ 1.0,	1023,	-1023,	"                      1" },
70*57718be8SEnji Cooper 	{ 1.0,	-1022,	1022,	"                      1" },
71*57718be8SEnji Cooper 	{ 0,	0,	0,	NULL }
72*57718be8SEnji Cooper };
73*57718be8SEnji Cooper 
74*57718be8SEnji Cooper struct ldexp_test ldexp_zero[] = {
75*57718be8SEnji Cooper 	{ 0.0,	-1,	SKIP,	"                      0" },
76*57718be8SEnji Cooper 	{ 0.0,	0,	SKIP,	"                      0" },
77*57718be8SEnji Cooper 	{ 0.0,	1,	SKIP,	"                      0" },
78*57718be8SEnji Cooper 	{ 0.0,	1024,	SKIP,	"                      0" },
79*57718be8SEnji Cooper 	{ 0.0,	1025,	SKIP,	"                      0" },
80*57718be8SEnji Cooper 	{ 0.0,	-1023,	SKIP,	"                      0" },
81*57718be8SEnji Cooper 	{ 0.0,	-1024,	SKIP,	"                      0" },
82*57718be8SEnji Cooper 	{ 0,	0,	0,	NULL }
83*57718be8SEnji Cooper };
84*57718be8SEnji Cooper 
85*57718be8SEnji Cooper struct ldexp_test ldexp_infinity[] = {
86*57718be8SEnji Cooper 	{ 1.0,	1024,	-1,	"                    inf" },
87*57718be8SEnji Cooper 	{ 1.0,	1024,	0,	"                    inf" },
88*57718be8SEnji Cooper 	{ 1.0,	1024,	1,	"                    inf" },
89*57718be8SEnji Cooper 	{ -1.0,	1024,	-1,	"                   -inf" },
90*57718be8SEnji Cooper 	{ -1.0,	1024,	0,	"                   -inf" },
91*57718be8SEnji Cooper 	{ -1.0,	1024,	1,	"                   -inf" },
92*57718be8SEnji Cooper 	{ 0,	0,	0,	NULL }
93*57718be8SEnji Cooper };
94*57718be8SEnji Cooper 
95*57718be8SEnji Cooper struct ldexp_test ldexp_overflow[] = {
96*57718be8SEnji Cooper 	{ 1.0,	1024,	SKIP,	"                    inf" },
97*57718be8SEnji Cooper 	{ 1.0,	1023,	1,	"                    inf" },
98*57718be8SEnji Cooper 	{ 1.0,	-1022,	2046,	"                    inf" },
99*57718be8SEnji Cooper 	{ 1.0,	1025,	SKIP,	"                    inf" },
100*57718be8SEnji Cooper 	{ -1.0,	1024,	SKIP,	"                   -inf" },
101*57718be8SEnji Cooper 	{ -1.0,	1023,	1,	"                   -inf" },
102*57718be8SEnji Cooper 	{ -1.0,	-1022,	2046,	"                   -inf" },
103*57718be8SEnji Cooper 	{ -1.0,	1025,	SKIP,	"                   -inf" },
104*57718be8SEnji Cooper 	{ 0,	0,	0,	NULL }
105*57718be8SEnji Cooper };
106*57718be8SEnji Cooper 
107*57718be8SEnji Cooper struct ldexp_test ldexp_denormal[] = {
108*57718be8SEnji Cooper 	{ 1.0,	-1023,	SKIP,	"1.1125369292536006915451e-308" },
109*57718be8SEnji Cooper 	{ 1.0,	-1022,	-1,	"1.1125369292536006915451e-308" },
110*57718be8SEnji Cooper 	{ 1.0,	1023,	-2046,	"1.1125369292536006915451e-308" },
111*57718be8SEnji Cooper 	{ 1.0,	-1024,	SKIP,	"5.5626846462680034577256e-309" },
112*57718be8SEnji Cooper 	{ 1.0,	-1074,	SKIP,	"4.9406564584124654417657e-324" },
113*57718be8SEnji Cooper 	{ -1.0,	-1023,	SKIP,	"-1.1125369292536006915451e-308" },
114*57718be8SEnji Cooper 	{ -1.0,	-1022,	-1,	"-1.1125369292536006915451e-308" },
115*57718be8SEnji Cooper 	{ -1.0,	1023,	-2046,	"-1.1125369292536006915451e-308" },
116*57718be8SEnji Cooper 	{ -1.0,	-1024,	SKIP,	"-5.5626846462680034577256e-309" },
117*57718be8SEnji Cooper 	{ -1.0,	-1074,	SKIP,	"-4.9406564584124654417657e-324" },
118*57718be8SEnji Cooper 	{ 0,	0,	0,	NULL }
119*57718be8SEnji Cooper };
120*57718be8SEnji Cooper 
121*57718be8SEnji Cooper struct ldexp_test ldexp_underflow[] = {
122*57718be8SEnji Cooper 	{ 1.0,	-1075,	SKIP,	"                      0" },
123*57718be8SEnji Cooper 	{ 1.0,	-1074,	-1,	"                      0" },
124*57718be8SEnji Cooper 	{ 1.0,	1023,	-2098,	"                      0" },
125*57718be8SEnji Cooper 	{ 1.0,	-1076,	SKIP,	"                      0" },
126*57718be8SEnji Cooper 	{ -1.0,	-1075,	SKIP,	"                     -0" },
127*57718be8SEnji Cooper 	{ -1.0,	-1074,	-1,	"                     -0" },
128*57718be8SEnji Cooper 	{ -1.0,	1023,	-2098,	"                     -0" },
129*57718be8SEnji Cooper 	{ -1.0,	-1076,	SKIP,	"                     -0" },
130*57718be8SEnji Cooper 	{ 0,	0,	0,	NULL }
131*57718be8SEnji Cooper };
132*57718be8SEnji Cooper 
133*57718be8SEnji Cooper struct ldexp_test ldexp_denormal_large[] = {
134*57718be8SEnji Cooper 	{ 1.0,	-1028,	1024,	"                 0.0625" },
135*57718be8SEnji Cooper 	{ 1.0,	-1028,	1025,	"                  0.125" },
136*57718be8SEnji Cooper 	{ 1.0,	-1028,	1026,	"                   0.25" },
137*57718be8SEnji Cooper 	{ 1.0,	-1028,	1027,	"                    0.5" },
138*57718be8SEnji Cooper 	{ 1.0,	-1028,	1028,	"                      1" },
139*57718be8SEnji Cooper 	{ 1.0,	-1028,	1029,	"                      2" },
140*57718be8SEnji Cooper 	{ 1.0,	-1028,	1030,	"                      4" },
141*57718be8SEnji Cooper 	{ 1.0,	-1028,	1040,	"                   4096" },
142*57718be8SEnji Cooper 	{ 1.0,	-1028,	1050,	"                4194304" },
143*57718be8SEnji Cooper 	{ 1.0,	-1028,	1060,	"             4294967296" },
144*57718be8SEnji Cooper 	{ 1.0,	-1028,	1100,	" 4722366482869645213696" },
145*57718be8SEnji Cooper 	{ 1.0,	-1028,	1200,	"5.9863107065073783529623e+51" },
146*57718be8SEnji Cooper 	{ 1.0,	-1028,	1300,	"7.5885503602567541832791e+81" },
147*57718be8SEnji Cooper 	{ 1.0,	-1028,	1400,	"9.6196304190416209014353e+111" },
148*57718be8SEnji Cooper 	{ 1.0,	-1028,	1500,	"1.2194330274671844653834e+142" },
149*57718be8SEnji Cooper 	{ 1.0,	-1028,	1600,	"1.5458150092069033378781e+172" },
150*57718be8SEnji Cooper 	{ 1.0,	-1028,	1700,	"1.9595533242629369747791e+202" },
151*57718be8SEnji Cooper 	{ 1.0,	-1028,	1800,	"2.4840289476811342962384e+232" },
152*57718be8SEnji Cooper 	{ 1.0,	-1028,	1900,	"3.1488807865122869393369e+262" },
153*57718be8SEnji Cooper 	{ 1.0,	-1028,	2000,	"3.9916806190694396233127e+292" },
154*57718be8SEnji Cooper 	{ 1.0,	-1028,	2046,	"2.808895523222368605827e+306" },
155*57718be8SEnji Cooper 	{ 1.0,	-1028,	2047,	"5.6177910464447372116541e+306" },
156*57718be8SEnji Cooper 	{ 1.0,	-1028,	2048,	"1.1235582092889474423308e+307" },
157*57718be8SEnji Cooper 	{ 1.0,	-1028,	2049,	"2.2471164185778948846616e+307" },
158*57718be8SEnji Cooper 	{ 1.0,	-1028,	2050,	"4.4942328371557897693233e+307" },
159*57718be8SEnji Cooper 	{ 1.0,	-1028,	2051,	"8.9884656743115795386465e+307" },
160*57718be8SEnji Cooper 	{ 0,	0,	0,	NULL }
161*57718be8SEnji Cooper };
162*57718be8SEnji Cooper 
163*57718be8SEnji Cooper static void
164*57718be8SEnji Cooper run_test(struct ldexp_test *table)
165*57718be8SEnji Cooper {
166*57718be8SEnji Cooper 	char outbuf[64];
167*57718be8SEnji Cooper 	size_t i;
168*57718be8SEnji Cooper 	double v;
169*57718be8SEnji Cooper 
170*57718be8SEnji Cooper 	for (i = 0; table->result != NULL; table++, i++) {
171*57718be8SEnji Cooper 
172*57718be8SEnji Cooper 		v = ldexp(table->x, table->exp1);
173*57718be8SEnji Cooper 
174*57718be8SEnji Cooper 		if (table->exp2 == SKIP)
175*57718be8SEnji Cooper 			continue;
176*57718be8SEnji Cooper 
177*57718be8SEnji Cooper 		v = ldexp(v, table->exp2);
178*57718be8SEnji Cooper 
179*57718be8SEnji Cooper 		(void)snprintf(outbuf, sizeof(outbuf), FORMAT, v);
180*57718be8SEnji Cooper 
181*57718be8SEnji Cooper 		ATF_CHECK_STREQ_MSG(table->result, outbuf,
182*57718be8SEnji Cooper 			    "Entry %zu:\n\tExp: \"%s\"\n\tAct: \"%s\"",
183*57718be8SEnji Cooper 			    i, table->result, outbuf);
184*57718be8SEnji Cooper 	}
185*57718be8SEnji Cooper }
186*57718be8SEnji Cooper 
187*57718be8SEnji Cooper /*
188*57718be8SEnji Cooper  * ldexp(3)
189*57718be8SEnji Cooper  */
190*57718be8SEnji Cooper ATF_TC(ldexp_exp2);
191*57718be8SEnji Cooper ATF_TC_HEAD(ldexp_exp2, tc)
192*57718be8SEnji Cooper {
193*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexp(x, n) == x * exp2(n)");
194*57718be8SEnji Cooper }
195*57718be8SEnji Cooper 
196*57718be8SEnji Cooper ATF_TC_BODY(ldexp_exp2, tc)
197*57718be8SEnji Cooper {
198*57718be8SEnji Cooper 	const double n[] = { 1, 2, 3, 10, 50, 100 };
199*57718be8SEnji Cooper #if __DBL_MIN_10_EXP__ <= -40
200*57718be8SEnji Cooper 	const double eps = 1.0e-40;
201*57718be8SEnji Cooper #else
202*57718be8SEnji Cooper 	const double eps = __DBL_MIN__*4.0;
203*57718be8SEnji Cooper #endif
204*57718be8SEnji Cooper 	const double x = 12.0;
205*57718be8SEnji Cooper 	double y;
206*57718be8SEnji Cooper 	size_t i;
207*57718be8SEnji Cooper 
208*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(n); i++) {
209*57718be8SEnji Cooper 
210*57718be8SEnji Cooper 		y = ldexp(x, n[i]);
211*57718be8SEnji Cooper 
212*57718be8SEnji Cooper 		if (fabs(y - (x * exp2(n[i]))) > eps) {
213*57718be8SEnji Cooper 			atf_tc_fail_nonfatal("ldexp(%0.01f, %0.01f) "
214*57718be8SEnji Cooper 			    "!= %0.01f * exp2(%0.01f)", x, n[i], x, n[i]);
215*57718be8SEnji Cooper 		}
216*57718be8SEnji Cooper 	}
217*57718be8SEnji Cooper }
218*57718be8SEnji Cooper 
219*57718be8SEnji Cooper ATF_TC(ldexp_nan);
220*57718be8SEnji Cooper ATF_TC_HEAD(ldexp_nan, tc)
221*57718be8SEnji Cooper {
222*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexp(NaN) == NaN");
223*57718be8SEnji Cooper }
224*57718be8SEnji Cooper 
225*57718be8SEnji Cooper ATF_TC_BODY(ldexp_nan, tc)
226*57718be8SEnji Cooper {
227*57718be8SEnji Cooper 	const double x = 0.0L / 0.0L;
228*57718be8SEnji Cooper 	double y;
229*57718be8SEnji Cooper 	size_t i;
230*57718be8SEnji Cooper 
231*57718be8SEnji Cooper 	ATF_REQUIRE(isnan(x) != 0);
232*57718be8SEnji Cooper 
233*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++) {
234*57718be8SEnji Cooper 		y = ldexp(x, exps[i]);
235*57718be8SEnji Cooper 		ATF_CHECK(isnan(y) != 0);
236*57718be8SEnji Cooper 	}
237*57718be8SEnji Cooper }
238*57718be8SEnji Cooper 
239*57718be8SEnji Cooper ATF_TC(ldexp_inf_neg);
240*57718be8SEnji Cooper ATF_TC_HEAD(ldexp_inf_neg, tc)
241*57718be8SEnji Cooper {
242*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexp(-Inf) == -Inf");
243*57718be8SEnji Cooper }
244*57718be8SEnji Cooper 
245*57718be8SEnji Cooper ATF_TC_BODY(ldexp_inf_neg, tc)
246*57718be8SEnji Cooper {
247*57718be8SEnji Cooper 	const double x = -1.0L / 0.0L;
248*57718be8SEnji Cooper 	size_t i;
249*57718be8SEnji Cooper 
250*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++)
251*57718be8SEnji Cooper 		ATF_CHECK(ldexp(x, exps[i]) == x);
252*57718be8SEnji Cooper }
253*57718be8SEnji Cooper 
254*57718be8SEnji Cooper ATF_TC(ldexp_inf_pos);
255*57718be8SEnji Cooper ATF_TC_HEAD(ldexp_inf_pos, tc)
256*57718be8SEnji Cooper {
257*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexp(+Inf) == +Inf");
258*57718be8SEnji Cooper }
259*57718be8SEnji Cooper 
260*57718be8SEnji Cooper ATF_TC_BODY(ldexp_inf_pos, tc)
261*57718be8SEnji Cooper {
262*57718be8SEnji Cooper 	const double x = 1.0L / 0.0L;
263*57718be8SEnji Cooper 	size_t i;
264*57718be8SEnji Cooper 
265*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++)
266*57718be8SEnji Cooper 		ATF_CHECK(ldexp(x, exps[i]) == x);
267*57718be8SEnji Cooper }
268*57718be8SEnji Cooper 
269*57718be8SEnji Cooper ATF_TC(ldexp_zero_neg);
270*57718be8SEnji Cooper ATF_TC_HEAD(ldexp_zero_neg, tc)
271*57718be8SEnji Cooper {
272*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexp(-0.0) == -0.0");
273*57718be8SEnji Cooper }
274*57718be8SEnji Cooper 
275*57718be8SEnji Cooper ATF_TC_BODY(ldexp_zero_neg, tc)
276*57718be8SEnji Cooper {
277*57718be8SEnji Cooper 	const double x = -0.0L;
278*57718be8SEnji Cooper 	double y;
279*57718be8SEnji Cooper 	size_t i;
280*57718be8SEnji Cooper 
281*57718be8SEnji Cooper 	ATF_REQUIRE(signbit(x) != 0);
282*57718be8SEnji Cooper 
283*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++) {
284*57718be8SEnji Cooper 		y = ldexp(x, exps[i]);
285*57718be8SEnji Cooper 		ATF_CHECK(x == y);
286*57718be8SEnji Cooper 		ATF_CHECK(signbit(y) != 0);
287*57718be8SEnji Cooper 	}
288*57718be8SEnji Cooper }
289*57718be8SEnji Cooper 
290*57718be8SEnji Cooper ATF_TC(ldexp_zero_pos);
291*57718be8SEnji Cooper ATF_TC_HEAD(ldexp_zero_pos, tc)
292*57718be8SEnji Cooper {
293*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexp(+0.0) == +0.0");
294*57718be8SEnji Cooper }
295*57718be8SEnji Cooper 
296*57718be8SEnji Cooper ATF_TC_BODY(ldexp_zero_pos, tc)
297*57718be8SEnji Cooper {
298*57718be8SEnji Cooper 	const double x = 0.0L;
299*57718be8SEnji Cooper 	double y;
300*57718be8SEnji Cooper 	size_t i;
301*57718be8SEnji Cooper 
302*57718be8SEnji Cooper 	ATF_REQUIRE(signbit(x) == 0);
303*57718be8SEnji Cooper 
304*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++) {
305*57718be8SEnji Cooper 		y = ldexp(x, exps[i]);
306*57718be8SEnji Cooper 		ATF_CHECK(x == y);
307*57718be8SEnji Cooper 		ATF_CHECK(signbit(y) == 0);
308*57718be8SEnji Cooper 	}
309*57718be8SEnji Cooper }
310*57718be8SEnji Cooper 
311*57718be8SEnji Cooper /*
312*57718be8SEnji Cooper  * ldexpf(3)
313*57718be8SEnji Cooper  */
314*57718be8SEnji Cooper 
315*57718be8SEnji Cooper ATF_TC(ldexpf_exp2f);
316*57718be8SEnji Cooper ATF_TC_HEAD(ldexpf_exp2f, tc)
317*57718be8SEnji Cooper {
318*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(x, n) == x * exp2f(n)");
319*57718be8SEnji Cooper }
320*57718be8SEnji Cooper 
321*57718be8SEnji Cooper ATF_TC_BODY(ldexpf_exp2f, tc)
322*57718be8SEnji Cooper {
323*57718be8SEnji Cooper 	const float n[] = { 1, 2, 3, 10, 50, 100 };
324*57718be8SEnji Cooper 	const float eps = 1.0e-9;
325*57718be8SEnji Cooper 	const float x = 12.0;
326*57718be8SEnji Cooper 	float y;
327*57718be8SEnji Cooper 	size_t i;
328*57718be8SEnji Cooper 
329*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(n); i++) {
330*57718be8SEnji Cooper 
331*57718be8SEnji Cooper 		y = ldexpf(x, n[i]);
332*57718be8SEnji Cooper 
333*57718be8SEnji Cooper 		if (fabsf(y - (x * exp2f(n[i]))) > eps) {
334*57718be8SEnji Cooper 			atf_tc_fail_nonfatal("ldexpf(%0.01f, %0.01f) "
335*57718be8SEnji Cooper 			    "!= %0.01f * exp2f(%0.01f)", x, n[i], x, n[i]);
336*57718be8SEnji Cooper 		}
337*57718be8SEnji Cooper 	}
338*57718be8SEnji Cooper }
339*57718be8SEnji Cooper 
340*57718be8SEnji Cooper ATF_TC(ldexpf_nan);
341*57718be8SEnji Cooper ATF_TC_HEAD(ldexpf_nan, tc)
342*57718be8SEnji Cooper {
343*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(NaN) == NaN");
344*57718be8SEnji Cooper }
345*57718be8SEnji Cooper 
346*57718be8SEnji Cooper ATF_TC_BODY(ldexpf_nan, tc)
347*57718be8SEnji Cooper {
348*57718be8SEnji Cooper 	const float x = 0.0L / 0.0L;
349*57718be8SEnji Cooper 	float y;
350*57718be8SEnji Cooper 	size_t i;
351*57718be8SEnji Cooper 
352*57718be8SEnji Cooper 	ATF_REQUIRE(isnan(x) != 0);
353*57718be8SEnji Cooper 
354*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++) {
355*57718be8SEnji Cooper 		y = ldexpf(x, exps[i]);
356*57718be8SEnji Cooper 		ATF_CHECK(isnan(y) != 0);
357*57718be8SEnji Cooper 	}
358*57718be8SEnji Cooper }
359*57718be8SEnji Cooper 
360*57718be8SEnji Cooper ATF_TC(ldexpf_inf_neg);
361*57718be8SEnji Cooper ATF_TC_HEAD(ldexpf_inf_neg, tc)
362*57718be8SEnji Cooper {
363*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(-Inf) == -Inf");
364*57718be8SEnji Cooper }
365*57718be8SEnji Cooper 
366*57718be8SEnji Cooper ATF_TC_BODY(ldexpf_inf_neg, tc)
367*57718be8SEnji Cooper {
368*57718be8SEnji Cooper 	const float x = -1.0L / 0.0L;
369*57718be8SEnji Cooper 	size_t i;
370*57718be8SEnji Cooper 
371*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++)
372*57718be8SEnji Cooper 		ATF_CHECK(ldexpf(x, exps[i]) == x);
373*57718be8SEnji Cooper }
374*57718be8SEnji Cooper 
375*57718be8SEnji Cooper ATF_TC(ldexpf_inf_pos);
376*57718be8SEnji Cooper ATF_TC_HEAD(ldexpf_inf_pos, tc)
377*57718be8SEnji Cooper {
378*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(+Inf) == +Inf");
379*57718be8SEnji Cooper }
380*57718be8SEnji Cooper 
381*57718be8SEnji Cooper ATF_TC_BODY(ldexpf_inf_pos, tc)
382*57718be8SEnji Cooper {
383*57718be8SEnji Cooper 	const float x = 1.0L / 0.0L;
384*57718be8SEnji Cooper 	size_t i;
385*57718be8SEnji Cooper 
386*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++)
387*57718be8SEnji Cooper 		ATF_CHECK(ldexpf(x, exps[i]) == x);
388*57718be8SEnji Cooper }
389*57718be8SEnji Cooper 
390*57718be8SEnji Cooper ATF_TC(ldexpf_zero_neg);
391*57718be8SEnji Cooper ATF_TC_HEAD(ldexpf_zero_neg, tc)
392*57718be8SEnji Cooper {
393*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(-0.0) == -0.0");
394*57718be8SEnji Cooper }
395*57718be8SEnji Cooper 
396*57718be8SEnji Cooper ATF_TC_BODY(ldexpf_zero_neg, tc)
397*57718be8SEnji Cooper {
398*57718be8SEnji Cooper 	const float x = -0.0L;
399*57718be8SEnji Cooper 	float y;
400*57718be8SEnji Cooper 	size_t i;
401*57718be8SEnji Cooper 
402*57718be8SEnji Cooper 	ATF_REQUIRE(signbit(x) != 0);
403*57718be8SEnji Cooper 
404*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++) {
405*57718be8SEnji Cooper 		y = ldexpf(x, exps[i]);
406*57718be8SEnji Cooper 		ATF_CHECK(x == y);
407*57718be8SEnji Cooper 		ATF_CHECK(signbit(y) != 0);
408*57718be8SEnji Cooper 	}
409*57718be8SEnji Cooper }
410*57718be8SEnji Cooper 
411*57718be8SEnji Cooper ATF_TC(ldexpf_zero_pos);
412*57718be8SEnji Cooper ATF_TC_HEAD(ldexpf_zero_pos, tc)
413*57718be8SEnji Cooper {
414*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test ldexpf(+0.0) == +0.0");
415*57718be8SEnji Cooper }
416*57718be8SEnji Cooper 
417*57718be8SEnji Cooper ATF_TC_BODY(ldexpf_zero_pos, tc)
418*57718be8SEnji Cooper {
419*57718be8SEnji Cooper 	const float x = 0.0L;
420*57718be8SEnji Cooper 	float y;
421*57718be8SEnji Cooper 	size_t i;
422*57718be8SEnji Cooper 
423*57718be8SEnji Cooper 	ATF_REQUIRE(signbit(x) == 0);
424*57718be8SEnji Cooper 
425*57718be8SEnji Cooper 	for (i = 0; i < __arraycount(exps); i++) {
426*57718be8SEnji Cooper 		y = ldexpf(x, exps[i]);
427*57718be8SEnji Cooper 		ATF_CHECK(x == y);
428*57718be8SEnji Cooper 		ATF_CHECK(signbit(y) == 0);
429*57718be8SEnji Cooper 	}
430*57718be8SEnji Cooper }
431*57718be8SEnji Cooper 
432*57718be8SEnji Cooper #define TEST(name, desc)						\
433*57718be8SEnji Cooper 	ATF_TC(name);							\
434*57718be8SEnji Cooper 	ATF_TC_HEAD(name, tc)						\
435*57718be8SEnji Cooper 	{								\
436*57718be8SEnji Cooper 									\
437*57718be8SEnji Cooper 		atf_tc_set_md_var(tc, "descr",				\
438*57718be8SEnji Cooper 		    "Test ldexp(3) for " ___STRING(desc));		\
439*57718be8SEnji Cooper 	}								\
440*57718be8SEnji Cooper 	ATF_TC_BODY(name, tc)						\
441*57718be8SEnji Cooper 	{								\
442*57718be8SEnji Cooper 		if (strcmp("vax", MACHINE_ARCH) == 0)			\
443*57718be8SEnji Cooper 			atf_tc_skip("Test not valid for " MACHINE_ARCH); \
444*57718be8SEnji Cooper 		run_test(name);						\
445*57718be8SEnji Cooper 	}
446*57718be8SEnji Cooper 
447*57718be8SEnji Cooper TEST(ldexp_basic, basics)
448*57718be8SEnji Cooper TEST(ldexp_zero, zero)
449*57718be8SEnji Cooper TEST(ldexp_infinity, infinity)
450*57718be8SEnji Cooper TEST(ldexp_overflow, overflow)
451*57718be8SEnji Cooper TEST(ldexp_denormal, denormal)
452*57718be8SEnji Cooper TEST(ldexp_denormal_large, large)
453*57718be8SEnji Cooper TEST(ldexp_underflow, underflow)
454*57718be8SEnji Cooper 
455*57718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
456*57718be8SEnji Cooper {
457*57718be8SEnji Cooper 
458*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_basic);
459*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_zero);
460*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_infinity);
461*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_overflow);
462*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_denormal);
463*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_underflow);
464*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_denormal_large);
465*57718be8SEnji Cooper 
466*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_exp2);
467*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_nan);
468*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_inf_neg);
469*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_inf_pos);
470*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_zero_neg);
471*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexp_zero_pos);
472*57718be8SEnji Cooper 
473*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexpf_exp2f);
474*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexpf_nan);
475*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexpf_inf_neg);
476*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexpf_inf_pos);
477*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexpf_zero_neg);
478*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, ldexpf_zero_pos);
479*57718be8SEnji Cooper 
480*57718be8SEnji Cooper 	return atf_no_error();
481*57718be8SEnji Cooper }
482