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