1*0a6a1f1dSLionel Sambuc /* $NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $ */
211be35a1SLionel Sambuc
311be35a1SLionel Sambuc /*-
411be35a1SLionel Sambuc * Copyright (c) 2011 The NetBSD Foundation, Inc.
511be35a1SLionel Sambuc * All rights reserved.
611be35a1SLionel Sambuc *
711be35a1SLionel Sambuc * This code is derived from software contributed to The NetBSD Foundation
811be35a1SLionel Sambuc * by Jukka Ruohonen.
911be35a1SLionel Sambuc *
1011be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without
1111be35a1SLionel Sambuc * modification, are permitted provided that the following conditions
1211be35a1SLionel Sambuc * are met:
1311be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
1411be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer.
1511be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
1611be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
1711be35a1SLionel Sambuc * documentation and/or other materials provided with the distribution.
1811be35a1SLionel Sambuc *
1911be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2011be35a1SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2111be35a1SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2211be35a1SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2311be35a1SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2411be35a1SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2511be35a1SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2611be35a1SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2711be35a1SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2811be35a1SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2911be35a1SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE.
3011be35a1SLionel Sambuc */
3111be35a1SLionel Sambuc #include <sys/cdefs.h>
32*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $");
3311be35a1SLionel Sambuc
3411be35a1SLionel Sambuc #include <math.h>
3511be35a1SLionel Sambuc #include <limits.h>
3611be35a1SLionel Sambuc #include <float.h>
3711be35a1SLionel Sambuc #include <errno.h>
3811be35a1SLionel Sambuc
3911be35a1SLionel Sambuc #include <atf-c.h>
4011be35a1SLionel Sambuc
4111be35a1SLionel Sambuc static const int exps[] = { 0, 1, -1, 100, -100 };
4211be35a1SLionel Sambuc
4311be35a1SLionel Sambuc /* tests here do not require specific precision, so we just use double */
4411be35a1SLionel Sambuc struct testcase {
4511be35a1SLionel Sambuc int exp;
4611be35a1SLionel Sambuc double inval;
4711be35a1SLionel Sambuc double result;
4811be35a1SLionel Sambuc int error;
4911be35a1SLionel Sambuc };
5011be35a1SLionel Sambuc struct testcase test_vals[] = {
5111be35a1SLionel Sambuc { 0, 1.00085, 1.00085, 0 },
5211be35a1SLionel Sambuc { 0, 0.99755, 0.99755, 0 },
5311be35a1SLionel Sambuc { 0, -1.00085, -1.00085, 0 },
5411be35a1SLionel Sambuc { 0, -0.99755, -0.99755, 0 },
5511be35a1SLionel Sambuc { 1, 1.00085, 2.0* 1.00085, 0 },
5611be35a1SLionel Sambuc { 1, 0.99755, 2.0* 0.99755, 0 },
5711be35a1SLionel Sambuc { 1, -1.00085, 2.0* -1.00085, 0 },
5811be35a1SLionel Sambuc { 1, -0.99755, 2.0* -0.99755, 0 },
5911be35a1SLionel Sambuc
6011be35a1SLionel Sambuc /*
6111be35a1SLionel Sambuc * We could add more corner test cases here, but we would have to
6211be35a1SLionel Sambuc * add some ifdefs for the exact format and use a reliable
6311be35a1SLionel Sambuc * generator program - bail for now and only do trivial stuff above.
6411be35a1SLionel Sambuc */
6511be35a1SLionel Sambuc };
6611be35a1SLionel Sambuc
6711be35a1SLionel Sambuc /*
6811be35a1SLionel Sambuc * scalbn(3)
6911be35a1SLionel Sambuc */
7011be35a1SLionel Sambuc ATF_TC(scalbn_val);
ATF_TC_HEAD(scalbn_val,tc)7111be35a1SLionel Sambuc ATF_TC_HEAD(scalbn_val, tc)
7211be35a1SLionel Sambuc {
7311be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbn() for a few values");
7411be35a1SLionel Sambuc }
7511be35a1SLionel Sambuc
ATF_TC_BODY(scalbn_val,tc)7611be35a1SLionel Sambuc ATF_TC_BODY(scalbn_val, tc)
7711be35a1SLionel Sambuc {
7811be35a1SLionel Sambuc const struct testcase *tests = test_vals;
7911be35a1SLionel Sambuc const size_t tcnt = __arraycount(test_vals);
8011be35a1SLionel Sambuc size_t i;
8111be35a1SLionel Sambuc double rv;
8211be35a1SLionel Sambuc
8311be35a1SLionel Sambuc for (i = 0; i < tcnt; i++) {
8411be35a1SLionel Sambuc rv = scalbn(tests[i].inval, tests[i].exp);
8511be35a1SLionel Sambuc ATF_CHECK_EQ_MSG(errno, tests[i].error,
8611be35a1SLionel Sambuc "test %zu: errno %d instead of %d", i, errno,
8711be35a1SLionel Sambuc tests[i].error);
8811be35a1SLionel Sambuc ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*DBL_EPSILON,
8911be35a1SLionel Sambuc "test %zu: return value %g instead of %g (difference %g)",
9011be35a1SLionel Sambuc i, rv, tests[i].result, tests[i].result-rv);
9111be35a1SLionel Sambuc }
9211be35a1SLionel Sambuc }
9311be35a1SLionel Sambuc
9411be35a1SLionel Sambuc ATF_TC(scalbn_nan);
ATF_TC_HEAD(scalbn_nan,tc)9511be35a1SLionel Sambuc ATF_TC_HEAD(scalbn_nan, tc)
9611be35a1SLionel Sambuc {
9711be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN");
9811be35a1SLionel Sambuc }
9911be35a1SLionel Sambuc
ATF_TC_BODY(scalbn_nan,tc)10011be35a1SLionel Sambuc ATF_TC_BODY(scalbn_nan, tc)
10111be35a1SLionel Sambuc {
10211be35a1SLionel Sambuc const double x = 0.0L / 0.0L;
10311be35a1SLionel Sambuc double y;
10411be35a1SLionel Sambuc size_t i;
10511be35a1SLionel Sambuc
10611be35a1SLionel Sambuc ATF_REQUIRE(isnan(x) != 0);
10711be35a1SLionel Sambuc
10811be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
10911be35a1SLionel Sambuc y = scalbn(x, exps[i]);
11011be35a1SLionel Sambuc ATF_CHECK(isnan(y) != 0);
11111be35a1SLionel Sambuc }
11211be35a1SLionel Sambuc }
11311be35a1SLionel Sambuc
11411be35a1SLionel Sambuc ATF_TC(scalbn_inf_neg);
ATF_TC_HEAD(scalbn_inf_neg,tc)11511be35a1SLionel Sambuc ATF_TC_HEAD(scalbn_inf_neg, tc)
11611be35a1SLionel Sambuc {
11711be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbn(-Inf, n) == -Inf");
11811be35a1SLionel Sambuc }
11911be35a1SLionel Sambuc
ATF_TC_BODY(scalbn_inf_neg,tc)12011be35a1SLionel Sambuc ATF_TC_BODY(scalbn_inf_neg, tc)
12111be35a1SLionel Sambuc {
12211be35a1SLionel Sambuc const double x = -1.0L / 0.0L;
12311be35a1SLionel Sambuc size_t i;
12411be35a1SLionel Sambuc
12511be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++)
12611be35a1SLionel Sambuc ATF_CHECK(scalbn(x, exps[i]) == x);
12711be35a1SLionel Sambuc }
12811be35a1SLionel Sambuc
12911be35a1SLionel Sambuc ATF_TC(scalbn_inf_pos);
ATF_TC_HEAD(scalbn_inf_pos,tc)13011be35a1SLionel Sambuc ATF_TC_HEAD(scalbn_inf_pos, tc)
13111be35a1SLionel Sambuc {
13211be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbn(+Inf, n) == +Inf");
13311be35a1SLionel Sambuc }
13411be35a1SLionel Sambuc
ATF_TC_BODY(scalbn_inf_pos,tc)13511be35a1SLionel Sambuc ATF_TC_BODY(scalbn_inf_pos, tc)
13611be35a1SLionel Sambuc {
13711be35a1SLionel Sambuc const double x = 1.0L / 0.0L;
13811be35a1SLionel Sambuc size_t i;
13911be35a1SLionel Sambuc
14011be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++)
14111be35a1SLionel Sambuc ATF_CHECK(scalbn(x, exps[i]) == x);
14211be35a1SLionel Sambuc }
14311be35a1SLionel Sambuc
14411be35a1SLionel Sambuc ATF_TC(scalbn_ldexp);
ATF_TC_HEAD(scalbn_ldexp,tc)14511be35a1SLionel Sambuc ATF_TC_HEAD(scalbn_ldexp, tc)
14611be35a1SLionel Sambuc {
14711be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)");
14811be35a1SLionel Sambuc }
14911be35a1SLionel Sambuc
ATF_TC_BODY(scalbn_ldexp,tc)15011be35a1SLionel Sambuc ATF_TC_BODY(scalbn_ldexp, tc)
15111be35a1SLionel Sambuc {
15211be35a1SLionel Sambuc #if FLT_RADIX == 2
15311be35a1SLionel Sambuc const double x = 2.91288191221812821;
15411be35a1SLionel Sambuc double y;
15511be35a1SLionel Sambuc size_t i;
15611be35a1SLionel Sambuc
15711be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
15811be35a1SLionel Sambuc y = scalbn(x, exps[i]);
15911be35a1SLionel Sambuc ATF_CHECK_MSG(y == ldexp(x, exps[i]), "test %zu: exponent=%d, "
16011be35a1SLionel Sambuc "y=%g, expected %g (diff: %g)", i, exps[i], y,
16111be35a1SLionel Sambuc ldexp(x, exps[i]), y - ldexp(x, exps[i]));
16211be35a1SLionel Sambuc }
16311be35a1SLionel Sambuc #endif
16411be35a1SLionel Sambuc }
16511be35a1SLionel Sambuc
16611be35a1SLionel Sambuc ATF_TC(scalbn_zero_neg);
ATF_TC_HEAD(scalbn_zero_neg,tc)16711be35a1SLionel Sambuc ATF_TC_HEAD(scalbn_zero_neg, tc)
16811be35a1SLionel Sambuc {
16911be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0");
17011be35a1SLionel Sambuc }
17111be35a1SLionel Sambuc
ATF_TC_BODY(scalbn_zero_neg,tc)17211be35a1SLionel Sambuc ATF_TC_BODY(scalbn_zero_neg, tc)
17311be35a1SLionel Sambuc {
17411be35a1SLionel Sambuc const double x = -0.0L;
17511be35a1SLionel Sambuc double y;
17611be35a1SLionel Sambuc size_t i;
17711be35a1SLionel Sambuc
17811be35a1SLionel Sambuc ATF_REQUIRE(signbit(x) != 0);
17911be35a1SLionel Sambuc
18011be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
18111be35a1SLionel Sambuc y = scalbn(x, exps[i]);
18211be35a1SLionel Sambuc ATF_CHECK(x == y);
18311be35a1SLionel Sambuc ATF_CHECK(signbit(y) != 0);
18411be35a1SLionel Sambuc }
18511be35a1SLionel Sambuc }
18611be35a1SLionel Sambuc
18711be35a1SLionel Sambuc ATF_TC(scalbn_zero_pos);
ATF_TC_HEAD(scalbn_zero_pos,tc)18811be35a1SLionel Sambuc ATF_TC_HEAD(scalbn_zero_pos, tc)
18911be35a1SLionel Sambuc {
19011be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbn(+0.0, n) == +0.0");
19111be35a1SLionel Sambuc }
19211be35a1SLionel Sambuc
ATF_TC_BODY(scalbn_zero_pos,tc)19311be35a1SLionel Sambuc ATF_TC_BODY(scalbn_zero_pos, tc)
19411be35a1SLionel Sambuc {
19511be35a1SLionel Sambuc const double x = 0.0L;
19611be35a1SLionel Sambuc double y;
19711be35a1SLionel Sambuc size_t i;
19811be35a1SLionel Sambuc
19911be35a1SLionel Sambuc ATF_REQUIRE(signbit(x) == 0);
20011be35a1SLionel Sambuc
20111be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
20211be35a1SLionel Sambuc y = scalbn(x, exps[i]);
20311be35a1SLionel Sambuc ATF_CHECK(x == y);
20411be35a1SLionel Sambuc ATF_CHECK(signbit(y) == 0);
20511be35a1SLionel Sambuc }
20611be35a1SLionel Sambuc }
20711be35a1SLionel Sambuc
20811be35a1SLionel Sambuc /*
20911be35a1SLionel Sambuc * scalbnf(3)
21011be35a1SLionel Sambuc */
21111be35a1SLionel Sambuc ATF_TC(scalbnf_val);
ATF_TC_HEAD(scalbnf_val,tc)21211be35a1SLionel Sambuc ATF_TC_HEAD(scalbnf_val, tc)
21311be35a1SLionel Sambuc {
21411be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnf() for a few values");
21511be35a1SLionel Sambuc }
21611be35a1SLionel Sambuc
ATF_TC_BODY(scalbnf_val,tc)21711be35a1SLionel Sambuc ATF_TC_BODY(scalbnf_val, tc)
21811be35a1SLionel Sambuc {
21911be35a1SLionel Sambuc const struct testcase *tests = test_vals;
22011be35a1SLionel Sambuc const size_t tcnt = __arraycount(test_vals);
22111be35a1SLionel Sambuc size_t i;
22211be35a1SLionel Sambuc double rv;
22311be35a1SLionel Sambuc
22411be35a1SLionel Sambuc for (i = 0; i < tcnt; i++) {
22511be35a1SLionel Sambuc rv = scalbnf(tests[i].inval, tests[i].exp);
22611be35a1SLionel Sambuc ATF_CHECK_EQ_MSG(errno, tests[i].error,
22711be35a1SLionel Sambuc "test %zu: errno %d instead of %d", i, errno,
22811be35a1SLionel Sambuc tests[i].error);
22911be35a1SLionel Sambuc ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*FLT_EPSILON,
23011be35a1SLionel Sambuc "test %zu: return value %g instead of %g (difference %g)",
23111be35a1SLionel Sambuc i, rv, tests[i].result, tests[i].result-rv);
23211be35a1SLionel Sambuc }
23311be35a1SLionel Sambuc }
23411be35a1SLionel Sambuc
23511be35a1SLionel Sambuc ATF_TC(scalbnf_nan);
ATF_TC_HEAD(scalbnf_nan,tc)23611be35a1SLionel Sambuc ATF_TC_HEAD(scalbnf_nan, tc)
23711be35a1SLionel Sambuc {
23811be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN");
23911be35a1SLionel Sambuc }
24011be35a1SLionel Sambuc
ATF_TC_BODY(scalbnf_nan,tc)24111be35a1SLionel Sambuc ATF_TC_BODY(scalbnf_nan, tc)
24211be35a1SLionel Sambuc {
24311be35a1SLionel Sambuc const float x = 0.0L / 0.0L;
24411be35a1SLionel Sambuc float y;
24511be35a1SLionel Sambuc size_t i;
24611be35a1SLionel Sambuc
24711be35a1SLionel Sambuc ATF_REQUIRE(isnan(x) != 0);
24811be35a1SLionel Sambuc
24911be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
25011be35a1SLionel Sambuc y = scalbnf(x, exps[i]);
25111be35a1SLionel Sambuc ATF_CHECK(isnan(y) != 0);
25211be35a1SLionel Sambuc }
25311be35a1SLionel Sambuc }
25411be35a1SLionel Sambuc
25511be35a1SLionel Sambuc ATF_TC(scalbnf_inf_neg);
ATF_TC_HEAD(scalbnf_inf_neg,tc)25611be35a1SLionel Sambuc ATF_TC_HEAD(scalbnf_inf_neg, tc)
25711be35a1SLionel Sambuc {
25811be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnf(-Inf, n) == -Inf");
25911be35a1SLionel Sambuc }
26011be35a1SLionel Sambuc
ATF_TC_BODY(scalbnf_inf_neg,tc)26111be35a1SLionel Sambuc ATF_TC_BODY(scalbnf_inf_neg, tc)
26211be35a1SLionel Sambuc {
26311be35a1SLionel Sambuc const float x = -1.0L / 0.0L;
26411be35a1SLionel Sambuc size_t i;
26511be35a1SLionel Sambuc
26611be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++)
26711be35a1SLionel Sambuc ATF_CHECK(scalbnf(x, exps[i]) == x);
26811be35a1SLionel Sambuc }
26911be35a1SLionel Sambuc
27011be35a1SLionel Sambuc ATF_TC(scalbnf_inf_pos);
ATF_TC_HEAD(scalbnf_inf_pos,tc)27111be35a1SLionel Sambuc ATF_TC_HEAD(scalbnf_inf_pos, tc)
27211be35a1SLionel Sambuc {
27311be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnf(+Inf, n) == +Inf");
27411be35a1SLionel Sambuc }
27511be35a1SLionel Sambuc
ATF_TC_BODY(scalbnf_inf_pos,tc)27611be35a1SLionel Sambuc ATF_TC_BODY(scalbnf_inf_pos, tc)
27711be35a1SLionel Sambuc {
27811be35a1SLionel Sambuc const float x = 1.0L / 0.0L;
27911be35a1SLionel Sambuc size_t i;
28011be35a1SLionel Sambuc
28111be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++)
28211be35a1SLionel Sambuc ATF_CHECK(scalbnf(x, exps[i]) == x);
28311be35a1SLionel Sambuc }
28411be35a1SLionel Sambuc
28511be35a1SLionel Sambuc ATF_TC(scalbnf_ldexpf);
ATF_TC_HEAD(scalbnf_ldexpf,tc)28611be35a1SLionel Sambuc ATF_TC_HEAD(scalbnf_ldexpf, tc)
28711be35a1SLionel Sambuc {
28811be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)");
28911be35a1SLionel Sambuc }
29011be35a1SLionel Sambuc
ATF_TC_BODY(scalbnf_ldexpf,tc)29111be35a1SLionel Sambuc ATF_TC_BODY(scalbnf_ldexpf, tc)
29211be35a1SLionel Sambuc {
29311be35a1SLionel Sambuc #if FLT_RADIX == 2
29411be35a1SLionel Sambuc const float x = 2.91288191221812821;
29511be35a1SLionel Sambuc float y;
29611be35a1SLionel Sambuc size_t i;
29711be35a1SLionel Sambuc
29811be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
29911be35a1SLionel Sambuc y = scalbnf(x, exps[i]);
30011be35a1SLionel Sambuc ATF_CHECK_MSG(y == ldexpf(x, exps[i]),
30111be35a1SLionel Sambuc "test %zu: exponent=%d, y=%g ldexpf returns %g (diff: %g)",
30211be35a1SLionel Sambuc i, exps[i], y, ldexpf(x, exps[i]), y-ldexpf(x, exps[i]));
30311be35a1SLionel Sambuc }
30411be35a1SLionel Sambuc #endif
30511be35a1SLionel Sambuc }
30611be35a1SLionel Sambuc
30711be35a1SLionel Sambuc ATF_TC(scalbnf_zero_neg);
ATF_TC_HEAD(scalbnf_zero_neg,tc)30811be35a1SLionel Sambuc ATF_TC_HEAD(scalbnf_zero_neg, tc)
30911be35a1SLionel Sambuc {
31011be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0");
31111be35a1SLionel Sambuc }
31211be35a1SLionel Sambuc
ATF_TC_BODY(scalbnf_zero_neg,tc)31311be35a1SLionel Sambuc ATF_TC_BODY(scalbnf_zero_neg, tc)
31411be35a1SLionel Sambuc {
31511be35a1SLionel Sambuc const float x = -0.0L;
31611be35a1SLionel Sambuc float y;
31711be35a1SLionel Sambuc size_t i;
31811be35a1SLionel Sambuc
31911be35a1SLionel Sambuc ATF_REQUIRE(signbit(x) != 0);
32011be35a1SLionel Sambuc
32111be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
32211be35a1SLionel Sambuc y = scalbnf(x, exps[i]);
32311be35a1SLionel Sambuc ATF_CHECK(x == y);
32411be35a1SLionel Sambuc ATF_CHECK(signbit(y) != 0);
32511be35a1SLionel Sambuc }
32611be35a1SLionel Sambuc }
32711be35a1SLionel Sambuc
32811be35a1SLionel Sambuc ATF_TC(scalbnf_zero_pos);
ATF_TC_HEAD(scalbnf_zero_pos,tc)32911be35a1SLionel Sambuc ATF_TC_HEAD(scalbnf_zero_pos, tc)
33011be35a1SLionel Sambuc {
33111be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnf(+0.0, n) == +0.0");
33211be35a1SLionel Sambuc }
33311be35a1SLionel Sambuc
ATF_TC_BODY(scalbnf_zero_pos,tc)33411be35a1SLionel Sambuc ATF_TC_BODY(scalbnf_zero_pos, tc)
33511be35a1SLionel Sambuc {
33611be35a1SLionel Sambuc const float x = 0.0L;
33711be35a1SLionel Sambuc float y;
33811be35a1SLionel Sambuc size_t i;
33911be35a1SLionel Sambuc
34011be35a1SLionel Sambuc ATF_REQUIRE(signbit(x) == 0);
34111be35a1SLionel Sambuc
34211be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
34311be35a1SLionel Sambuc y = scalbnf(x, exps[i]);
34411be35a1SLionel Sambuc ATF_CHECK(x == y);
34511be35a1SLionel Sambuc ATF_CHECK(signbit(y) == 0);
34611be35a1SLionel Sambuc }
34711be35a1SLionel Sambuc }
34811be35a1SLionel Sambuc
34911be35a1SLionel Sambuc /*
35011be35a1SLionel Sambuc * scalbnl(3)
35111be35a1SLionel Sambuc */
35211be35a1SLionel Sambuc ATF_TC(scalbnl_val);
ATF_TC_HEAD(scalbnl_val,tc)35311be35a1SLionel Sambuc ATF_TC_HEAD(scalbnl_val, tc)
35411be35a1SLionel Sambuc {
35511be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnl() for a few values");
35611be35a1SLionel Sambuc }
35711be35a1SLionel Sambuc
ATF_TC_BODY(scalbnl_val,tc)35811be35a1SLionel Sambuc ATF_TC_BODY(scalbnl_val, tc)
35911be35a1SLionel Sambuc {
36011be35a1SLionel Sambuc #ifndef __HAVE_LONG_DOUBLE
36111be35a1SLionel Sambuc atf_tc_skip("Requires long double support");
36211be35a1SLionel Sambuc #else
36311be35a1SLionel Sambuc const struct testcase *tests = test_vals;
36411be35a1SLionel Sambuc const size_t tcnt = __arraycount(test_vals);
36511be35a1SLionel Sambuc size_t i;
36611be35a1SLionel Sambuc long double rv;
36711be35a1SLionel Sambuc
36811be35a1SLionel Sambuc for (i = 0; i < tcnt; i++) {
36911be35a1SLionel Sambuc rv = scalbnl(tests[i].inval, tests[i].exp);
37011be35a1SLionel Sambuc ATF_CHECK_EQ_MSG(errno, tests[i].error,
37111be35a1SLionel Sambuc "test %zu: errno %d instead of %d", i, errno,
37211be35a1SLionel Sambuc tests[i].error);
37311be35a1SLionel Sambuc ATF_CHECK_MSG(fabsl(rv-(long double)tests[i].result)<2.0*LDBL_EPSILON,
37411be35a1SLionel Sambuc "test %zu: return value %Lg instead of %Lg (difference %Lg)",
37511be35a1SLionel Sambuc i, rv, (long double)tests[i].result, (long double)tests[i].result-rv);
37611be35a1SLionel Sambuc }
37711be35a1SLionel Sambuc #endif
37811be35a1SLionel Sambuc }
37911be35a1SLionel Sambuc
38011be35a1SLionel Sambuc ATF_TC(scalbnl_nan);
ATF_TC_HEAD(scalbnl_nan,tc)38111be35a1SLionel Sambuc ATF_TC_HEAD(scalbnl_nan, tc)
38211be35a1SLionel Sambuc {
38311be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN");
38411be35a1SLionel Sambuc }
38511be35a1SLionel Sambuc
ATF_TC_BODY(scalbnl_nan,tc)38611be35a1SLionel Sambuc ATF_TC_BODY(scalbnl_nan, tc)
38711be35a1SLionel Sambuc {
38811be35a1SLionel Sambuc #ifndef __HAVE_LONG_DOUBLE
38911be35a1SLionel Sambuc atf_tc_skip("Requires long double support");
39011be35a1SLionel Sambuc #else
39111be35a1SLionel Sambuc const long double x = 0.0L / 0.0L;
39211be35a1SLionel Sambuc long double y;
39311be35a1SLionel Sambuc size_t i;
39411be35a1SLionel Sambuc
39511be35a1SLionel Sambuc if (isnan(x) == 0) {
39611be35a1SLionel Sambuc atf_tc_expect_fail("PR lib/45362");
39711be35a1SLionel Sambuc atf_tc_fail("(0.0L / 0.0L) != NaN");
39811be35a1SLionel Sambuc }
39911be35a1SLionel Sambuc
40011be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
40111be35a1SLionel Sambuc y = scalbnl(x, exps[i]);
40211be35a1SLionel Sambuc ATF_CHECK(isnan(y) != 0);
40311be35a1SLionel Sambuc }
40411be35a1SLionel Sambuc #endif
40511be35a1SLionel Sambuc }
40611be35a1SLionel Sambuc
40711be35a1SLionel Sambuc ATF_TC(scalbnl_inf_neg);
ATF_TC_HEAD(scalbnl_inf_neg,tc)40811be35a1SLionel Sambuc ATF_TC_HEAD(scalbnl_inf_neg, tc)
40911be35a1SLionel Sambuc {
41011be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnl(-Inf, n) == -Inf");
41111be35a1SLionel Sambuc }
41211be35a1SLionel Sambuc
ATF_TC_BODY(scalbnl_inf_neg,tc)41311be35a1SLionel Sambuc ATF_TC_BODY(scalbnl_inf_neg, tc)
41411be35a1SLionel Sambuc {
41511be35a1SLionel Sambuc #ifndef __HAVE_LONG_DOUBLE
41611be35a1SLionel Sambuc atf_tc_skip("Requires long double support");
41711be35a1SLionel Sambuc #else
41811be35a1SLionel Sambuc const long double x = -1.0L / 0.0L;
41911be35a1SLionel Sambuc size_t i;
42011be35a1SLionel Sambuc
42111be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++)
42211be35a1SLionel Sambuc ATF_CHECK(scalbnl(x, exps[i]) == x);
42311be35a1SLionel Sambuc #endif
42411be35a1SLionel Sambuc }
42511be35a1SLionel Sambuc
42611be35a1SLionel Sambuc ATF_TC(scalbnl_inf_pos);
ATF_TC_HEAD(scalbnl_inf_pos,tc)42711be35a1SLionel Sambuc ATF_TC_HEAD(scalbnl_inf_pos, tc)
42811be35a1SLionel Sambuc {
42911be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnl(+Inf, n) == +Inf");
43011be35a1SLionel Sambuc }
43111be35a1SLionel Sambuc
ATF_TC_BODY(scalbnl_inf_pos,tc)43211be35a1SLionel Sambuc ATF_TC_BODY(scalbnl_inf_pos, tc)
43311be35a1SLionel Sambuc {
43411be35a1SLionel Sambuc #ifndef __HAVE_LONG_DOUBLE
43511be35a1SLionel Sambuc atf_tc_skip("Requires long double support");
43611be35a1SLionel Sambuc #else
43711be35a1SLionel Sambuc const long double x = 1.0L / 0.0L;
43811be35a1SLionel Sambuc size_t i;
43911be35a1SLionel Sambuc
44011be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++)
44111be35a1SLionel Sambuc ATF_CHECK(scalbnl(x, exps[i]) == x);
44211be35a1SLionel Sambuc #endif
44311be35a1SLionel Sambuc }
44411be35a1SLionel Sambuc
44511be35a1SLionel Sambuc ATF_TC(scalbnl_zero_neg);
ATF_TC_HEAD(scalbnl_zero_neg,tc)44611be35a1SLionel Sambuc ATF_TC_HEAD(scalbnl_zero_neg, tc)
44711be35a1SLionel Sambuc {
44811be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnl(-0.0, n) == -0.0");
44911be35a1SLionel Sambuc }
45011be35a1SLionel Sambuc
ATF_TC_BODY(scalbnl_zero_neg,tc)45111be35a1SLionel Sambuc ATF_TC_BODY(scalbnl_zero_neg, tc)
45211be35a1SLionel Sambuc {
45311be35a1SLionel Sambuc #ifndef __HAVE_LONG_DOUBLE
45411be35a1SLionel Sambuc atf_tc_skip("Requires long double support");
45511be35a1SLionel Sambuc #else
45611be35a1SLionel Sambuc const long double x = -0.0L;
45711be35a1SLionel Sambuc long double y;
45811be35a1SLionel Sambuc size_t i;
45911be35a1SLionel Sambuc
46011be35a1SLionel Sambuc ATF_REQUIRE(signbit(x) != 0);
46111be35a1SLionel Sambuc
46211be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
46311be35a1SLionel Sambuc y = scalbnl(x, exps[i]);
46411be35a1SLionel Sambuc ATF_CHECK(x == y);
46511be35a1SLionel Sambuc ATF_CHECK(signbit(y) != 0);
46611be35a1SLionel Sambuc }
46711be35a1SLionel Sambuc #endif
46811be35a1SLionel Sambuc }
46911be35a1SLionel Sambuc
47011be35a1SLionel Sambuc ATF_TC(scalbnl_zero_pos);
ATF_TC_HEAD(scalbnl_zero_pos,tc)47111be35a1SLionel Sambuc ATF_TC_HEAD(scalbnl_zero_pos, tc)
47211be35a1SLionel Sambuc {
47311be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test scalbnl(+0.0, n) == +0.0");
47411be35a1SLionel Sambuc }
47511be35a1SLionel Sambuc
ATF_TC_BODY(scalbnl_zero_pos,tc)47611be35a1SLionel Sambuc ATF_TC_BODY(scalbnl_zero_pos, tc)
47711be35a1SLionel Sambuc {
47811be35a1SLionel Sambuc #ifndef __HAVE_LONG_DOUBLE
47911be35a1SLionel Sambuc atf_tc_skip("Requires long double support");
48011be35a1SLionel Sambuc #else
48111be35a1SLionel Sambuc const long double x = 0.0L;
48211be35a1SLionel Sambuc long double y;
48311be35a1SLionel Sambuc size_t i;
48411be35a1SLionel Sambuc
48511be35a1SLionel Sambuc ATF_REQUIRE(signbit(x) == 0);
48611be35a1SLionel Sambuc
48711be35a1SLionel Sambuc for (i = 0; i < __arraycount(exps); i++) {
48811be35a1SLionel Sambuc y = scalbnl(x, exps[i]);
48911be35a1SLionel Sambuc ATF_CHECK(x == y);
49011be35a1SLionel Sambuc ATF_CHECK(signbit(y) == 0);
49111be35a1SLionel Sambuc }
49211be35a1SLionel Sambuc #endif
49311be35a1SLionel Sambuc }
49411be35a1SLionel Sambuc
ATF_TP_ADD_TCS(tp)49511be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp)
49611be35a1SLionel Sambuc {
49711be35a1SLionel Sambuc
49811be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbn_val);
49911be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbn_nan);
50011be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbn_inf_neg);
50111be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbn_inf_pos);
50211be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbn_ldexp);
50311be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbn_zero_neg);
50411be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbn_zero_pos);
50511be35a1SLionel Sambuc
50611be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnf_val);
50711be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnf_nan);
50811be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnf_inf_neg);
50911be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnf_inf_pos);
51011be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnf_ldexpf);
51111be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnf_zero_neg);
51211be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnf_zero_pos);
51311be35a1SLionel Sambuc
51411be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnl_val);
51511be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnl_nan);
51611be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnl_inf_neg);
51711be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnl_inf_pos);
51811be35a1SLionel Sambuc /* ATF_TP_ADD_TC(tp, scalbnl_ldexp); */
51911be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnl_zero_neg);
52011be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, scalbnl_zero_pos);
52111be35a1SLionel Sambuc
52211be35a1SLionel Sambuc return atf_no_error();
52311be35a1SLionel Sambuc }
524