1dd66b5baSEnji Cooper /* $NetBSD: t_pow.c,v 1.5 2017/01/20 21:15:56 maya Exp $ */
257718be8SEnji Cooper
357718be8SEnji Cooper /*-
457718be8SEnji Cooper * Copyright (c) 2011 The NetBSD Foundation, Inc.
557718be8SEnji Cooper * All rights reserved.
657718be8SEnji Cooper *
757718be8SEnji Cooper * This code is derived from software contributed to The NetBSD Foundation
857718be8SEnji Cooper * by Jukka Ruohonen.
957718be8SEnji Cooper *
1057718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without
1157718be8SEnji Cooper * modification, are permitted provided that the following conditions
1257718be8SEnji Cooper * are met:
1357718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright
1457718be8SEnji Cooper * notice, this list of conditions and the following disclaimer.
1557718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
1657718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the
1757718be8SEnji Cooper * documentation and/or other materials provided with the distribution.
1857718be8SEnji Cooper *
1957718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2057718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2157718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2257718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2357718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2457718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2557718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2657718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2757718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2857718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2957718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE.
3057718be8SEnji Cooper */
3157718be8SEnji Cooper #include <sys/cdefs.h>
32dd66b5baSEnji Cooper __RCSID("$NetBSD: t_pow.c,v 1.5 2017/01/20 21:15:56 maya Exp $");
3357718be8SEnji Cooper
3457718be8SEnji Cooper #include <atf-c.h>
3557718be8SEnji Cooper #include <math.h>
3657718be8SEnji Cooper
3757718be8SEnji Cooper /*
3857718be8SEnji Cooper * pow(3)
3957718be8SEnji Cooper */
4057718be8SEnji Cooper ATF_TC(pow_nan_x);
ATF_TC_HEAD(pow_nan_x,tc)4157718be8SEnji Cooper ATF_TC_HEAD(pow_nan_x, tc)
4257718be8SEnji Cooper {
4357718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN");
4457718be8SEnji Cooper }
4557718be8SEnji Cooper
ATF_TC_BODY(pow_nan_x,tc)4657718be8SEnji Cooper ATF_TC_BODY(pow_nan_x, tc)
4757718be8SEnji Cooper {
4857718be8SEnji Cooper const double x = 0.0L / 0.0L;
4957718be8SEnji Cooper
5057718be8SEnji Cooper ATF_CHECK(isnan(pow(x, 2.0)) != 0);
5157718be8SEnji Cooper }
5257718be8SEnji Cooper
5357718be8SEnji Cooper ATF_TC(pow_nan_y);
ATF_TC_HEAD(pow_nan_y,tc)5457718be8SEnji Cooper ATF_TC_HEAD(pow_nan_y, tc)
5557718be8SEnji Cooper {
5657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN");
5757718be8SEnji Cooper }
5857718be8SEnji Cooper
ATF_TC_BODY(pow_nan_y,tc)5957718be8SEnji Cooper ATF_TC_BODY(pow_nan_y, tc)
6057718be8SEnji Cooper {
6157718be8SEnji Cooper const double y = 0.0L / 0.0L;
6257718be8SEnji Cooper
6357718be8SEnji Cooper ATF_CHECK(isnan(pow(2.0, y)) != 0);
6457718be8SEnji Cooper }
6557718be8SEnji Cooper
6657718be8SEnji Cooper ATF_TC(pow_inf_neg_x);
ATF_TC_HEAD(pow_inf_neg_x,tc)6757718be8SEnji Cooper ATF_TC_HEAD(pow_inf_neg_x, tc)
6857718be8SEnji Cooper {
6957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0");
7057718be8SEnji Cooper }
7157718be8SEnji Cooper
ATF_TC_BODY(pow_inf_neg_x,tc)7257718be8SEnji Cooper ATF_TC_BODY(pow_inf_neg_x, tc)
7357718be8SEnji Cooper {
7457718be8SEnji Cooper const double x = -1.0L / 0.0L;
7557718be8SEnji Cooper double z;
7657718be8SEnji Cooper
7757718be8SEnji Cooper /*
7857718be8SEnji Cooper * If y is odd, y > 0, and x is -Inf, -Inf is returned.
7957718be8SEnji Cooper * If y is even, y > 0, and x is -Inf, +Inf is returned.
8057718be8SEnji Cooper */
8157718be8SEnji Cooper z = pow(x, 3.0);
8257718be8SEnji Cooper
8357718be8SEnji Cooper if (isinf(z) == 0 || signbit(z) == 0)
8457718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-Inf, 3.0) != -Inf");
8557718be8SEnji Cooper
8657718be8SEnji Cooper z = pow(x, 4.0);
8757718be8SEnji Cooper
8857718be8SEnji Cooper if (isinf(z) == 0 || signbit(z) != 0)
8957718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-Inf, 4.0) != +Inf");
9057718be8SEnji Cooper
9157718be8SEnji Cooper /*
9257718be8SEnji Cooper * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
9357718be8SEnji Cooper * If y is even, y < 0, and x is -Inf, +0.0 is returned.
9457718be8SEnji Cooper */
9557718be8SEnji Cooper z = pow(x, -3.0);
9657718be8SEnji Cooper
9757718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) == 0)
9857718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-Inf, -3.0) != -0.0");
9957718be8SEnji Cooper
10057718be8SEnji Cooper z = pow(x, -4.0);
10157718be8SEnji Cooper
10257718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) != 0)
10357718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-Inf -4.0) != +0.0");
10457718be8SEnji Cooper }
10557718be8SEnji Cooper
10657718be8SEnji Cooper ATF_TC(pow_inf_neg_y);
ATF_TC_HEAD(pow_inf_neg_y,tc)10757718be8SEnji Cooper ATF_TC_HEAD(pow_inf_neg_y, tc)
10857718be8SEnji Cooper {
10957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0");
11057718be8SEnji Cooper }
11157718be8SEnji Cooper
ATF_TC_BODY(pow_inf_neg_y,tc)11257718be8SEnji Cooper ATF_TC_BODY(pow_inf_neg_y, tc)
11357718be8SEnji Cooper {
11457718be8SEnji Cooper const double y = -1.0L / 0.0L;
11557718be8SEnji Cooper double z;
11657718be8SEnji Cooper
11757718be8SEnji Cooper /*
11857718be8SEnji Cooper * If |x| < 1 and y is -Inf, +Inf is returned.
11957718be8SEnji Cooper * If |x| > 1 and y is -Inf, +0.0 is returned.
12057718be8SEnji Cooper */
12157718be8SEnji Cooper z = pow(0.1, y);
12257718be8SEnji Cooper
12357718be8SEnji Cooper if (isinf(z) == 0 || signbit(z) != 0)
12457718be8SEnji Cooper atf_tc_fail_nonfatal("pow(0.1, -Inf) != +Inf");
12557718be8SEnji Cooper
12657718be8SEnji Cooper z = pow(1.1, y);
12757718be8SEnji Cooper
12857718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) != 0)
12957718be8SEnji Cooper atf_tc_fail_nonfatal("pow(1.1, -Inf) != +0.0");
13057718be8SEnji Cooper }
13157718be8SEnji Cooper
13257718be8SEnji Cooper ATF_TC(pow_inf_pos_x);
ATF_TC_HEAD(pow_inf_pos_x,tc)13357718be8SEnji Cooper ATF_TC_HEAD(pow_inf_pos_x, tc)
13457718be8SEnji Cooper {
13557718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0");
13657718be8SEnji Cooper }
13757718be8SEnji Cooper
ATF_TC_BODY(pow_inf_pos_x,tc)13857718be8SEnji Cooper ATF_TC_BODY(pow_inf_pos_x, tc)
13957718be8SEnji Cooper {
14057718be8SEnji Cooper const double x = 1.0L / 0.0L;
14157718be8SEnji Cooper double z;
14257718be8SEnji Cooper
14357718be8SEnji Cooper /*
14457718be8SEnji Cooper * For y < 0, if x is +Inf, +0.0 is returned.
14557718be8SEnji Cooper * For y > 0, if x is +Inf, +Inf is returned.
14657718be8SEnji Cooper */
14757718be8SEnji Cooper z = pow(x, -2.0);
14857718be8SEnji Cooper
14957718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) != 0)
15057718be8SEnji Cooper atf_tc_fail_nonfatal("pow(+Inf, -2.0) != +0.0");
15157718be8SEnji Cooper
15257718be8SEnji Cooper z = pow(x, 2.0);
15357718be8SEnji Cooper
15457718be8SEnji Cooper if (isinf(z) == 0 || signbit(z) != 0)
15557718be8SEnji Cooper atf_tc_fail_nonfatal("pow(+Inf, 2.0) != +Inf");
15657718be8SEnji Cooper }
15757718be8SEnji Cooper
15857718be8SEnji Cooper ATF_TC(pow_inf_pos_y);
ATF_TC_HEAD(pow_inf_pos_y,tc)15957718be8SEnji Cooper ATF_TC_HEAD(pow_inf_pos_y, tc)
16057718be8SEnji Cooper {
16157718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0");
16257718be8SEnji Cooper }
16357718be8SEnji Cooper
ATF_TC_BODY(pow_inf_pos_y,tc)16457718be8SEnji Cooper ATF_TC_BODY(pow_inf_pos_y, tc)
16557718be8SEnji Cooper {
16657718be8SEnji Cooper const double y = 1.0L / 0.0L;
16757718be8SEnji Cooper double z;
16857718be8SEnji Cooper
16957718be8SEnji Cooper /*
17057718be8SEnji Cooper * If |x| < 1 and y is +Inf, +0.0 is returned.
17157718be8SEnji Cooper * If |x| > 1 and y is +Inf, +Inf is returned.
17257718be8SEnji Cooper */
17357718be8SEnji Cooper z = pow(0.1, y);
17457718be8SEnji Cooper
17557718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) != 0)
17657718be8SEnji Cooper atf_tc_fail_nonfatal("pow(0.1, +Inf) != +0.0");
17757718be8SEnji Cooper
17857718be8SEnji Cooper z = pow(1.1, y);
17957718be8SEnji Cooper
18057718be8SEnji Cooper if (isinf(z) == 0 || signbit(z) != 0)
18157718be8SEnji Cooper atf_tc_fail_nonfatal("pow(1.1, +Inf) != +Inf");
18257718be8SEnji Cooper }
18357718be8SEnji Cooper
18457718be8SEnji Cooper ATF_TC(pow_one_neg_x);
ATF_TC_HEAD(pow_one_neg_x,tc)18557718be8SEnji Cooper ATF_TC_HEAD(pow_one_neg_x, tc)
18657718be8SEnji Cooper {
18757718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0");
18857718be8SEnji Cooper }
18957718be8SEnji Cooper
ATF_TC_BODY(pow_one_neg_x,tc)19057718be8SEnji Cooper ATF_TC_BODY(pow_one_neg_x, tc)
19157718be8SEnji Cooper {
19257718be8SEnji Cooper const double infp = 1.0L / 0.0L;
19357718be8SEnji Cooper const double infn = -1.0L / 0.0L;
19457718be8SEnji Cooper
19557718be8SEnji Cooper /*
19657718be8SEnji Cooper * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
19757718be8SEnji Cooper */
19857718be8SEnji Cooper ATF_REQUIRE(isinf(infp) != 0);
19957718be8SEnji Cooper ATF_REQUIRE(isinf(infn) != 0);
20057718be8SEnji Cooper
20157718be8SEnji Cooper if (pow(-1.0, infp) != 1.0) {
20257718be8SEnji Cooper atf_tc_expect_fail("PR lib/45372");
20357718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-1.0, +Inf) != 1.0");
20457718be8SEnji Cooper }
20557718be8SEnji Cooper
20657718be8SEnji Cooper if (pow(-1.0, infn) != 1.0) {
20757718be8SEnji Cooper atf_tc_expect_fail("PR lib/45372");
20857718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-1.0, -Inf) != 1.0");
20957718be8SEnji Cooper }
21057718be8SEnji Cooper }
21157718be8SEnji Cooper
21257718be8SEnji Cooper ATF_TC(pow_one_pos_x);
ATF_TC_HEAD(pow_one_pos_x,tc)21357718be8SEnji Cooper ATF_TC_HEAD(pow_one_pos_x, tc)
21457718be8SEnji Cooper {
21557718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0");
21657718be8SEnji Cooper }
21757718be8SEnji Cooper
ATF_TC_BODY(pow_one_pos_x,tc)21857718be8SEnji Cooper ATF_TC_BODY(pow_one_pos_x, tc)
21957718be8SEnji Cooper {
22057718be8SEnji Cooper const double y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
22157718be8SEnji Cooper const double z = 0.0L / 0.0L;
22257718be8SEnji Cooper size_t i;
22357718be8SEnji Cooper
22457718be8SEnji Cooper /*
22557718be8SEnji Cooper * For any value of y (including NaN),
22657718be8SEnji Cooper * if x is 1.0, 1.0 shall be returned.
22757718be8SEnji Cooper */
22857718be8SEnji Cooper if (pow(1.0, z) != 1.0)
22957718be8SEnji Cooper atf_tc_fail_nonfatal("pow(1.0, NaN) != 1.0");
23057718be8SEnji Cooper
23157718be8SEnji Cooper for (i = 0; i < __arraycount(y); i++) {
23257718be8SEnji Cooper
23357718be8SEnji Cooper if (pow(1.0, y[i]) != 1.0)
23457718be8SEnji Cooper atf_tc_fail_nonfatal("pow(1.0, %0.01f) != 1.0", y[i]);
23557718be8SEnji Cooper }
23657718be8SEnji Cooper }
23757718be8SEnji Cooper
23857718be8SEnji Cooper ATF_TC(pow_zero_x);
ATF_TC_HEAD(pow_zero_x,tc)23957718be8SEnji Cooper ATF_TC_HEAD(pow_zero_x, tc)
24057718be8SEnji Cooper {
24157718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE");
24257718be8SEnji Cooper }
24357718be8SEnji Cooper
ATF_TC_BODY(pow_zero_x,tc)24457718be8SEnji Cooper ATF_TC_BODY(pow_zero_x, tc)
24557718be8SEnji Cooper {
24657718be8SEnji Cooper double z;
24757718be8SEnji Cooper
24857718be8SEnji Cooper /*
24957718be8SEnji Cooper * If x is +0.0 or -0.0, y > 0, and y
25057718be8SEnji Cooper * is an odd integer, x is returned.
25157718be8SEnji Cooper */
25257718be8SEnji Cooper z = pow(+0.0, 3.0);
25357718be8SEnji Cooper
25457718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) != 0)
25557718be8SEnji Cooper atf_tc_fail_nonfatal("pow(+0.0, 3.0) != +0.0");
25657718be8SEnji Cooper
25757718be8SEnji Cooper z = pow(-0.0, 3.0);
25857718be8SEnji Cooper
25957718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) == 0)
26057718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-0.0, 3.0) != -0.0");
26157718be8SEnji Cooper
26257718be8SEnji Cooper /*
26357718be8SEnji Cooper * If y > 0 and not an odd integer,
26457718be8SEnji Cooper * if x is +0.0 or -0.0, +0.0 is returned.
26557718be8SEnji Cooper */
26657718be8SEnji Cooper z = pow(+0.0, 4.0);
26757718be8SEnji Cooper
26857718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) != 0)
26957718be8SEnji Cooper atf_tc_fail_nonfatal("pow(+0.0, 4.0) != +0.0");
27057718be8SEnji Cooper
27157718be8SEnji Cooper z = pow(-0.0, 4.0);
27257718be8SEnji Cooper
27357718be8SEnji Cooper if (fabs(z) > 0.0 || signbit(z) != 0)
27457718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-0.0, 4.0) != +0.0");
27557718be8SEnji Cooper
27657718be8SEnji Cooper /*
27757718be8SEnji Cooper * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
27857718be8SEnji Cooper * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
27957718be8SEnji Cooper */
28057718be8SEnji Cooper z = pow(+0.0, -4.0);
28157718be8SEnji Cooper
28257718be8SEnji Cooper if (z != HUGE_VAL) {
28357718be8SEnji Cooper atf_tc_fail_nonfatal("pow(+0.0, -4.0) != HUGE_VAL");
28457718be8SEnji Cooper }
28557718be8SEnji Cooper
28657718be8SEnji Cooper z = pow(-0.0, -4.0);
28757718be8SEnji Cooper
28857718be8SEnji Cooper if (z != HUGE_VAL) {
28957718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-0.0, -4.0) != HUGE_VAL");
29057718be8SEnji Cooper }
29157718be8SEnji Cooper
29257718be8SEnji Cooper z = pow(+0.0, -5.0);
29357718be8SEnji Cooper
29457718be8SEnji Cooper if (z != HUGE_VAL) {
29557718be8SEnji Cooper atf_tc_fail_nonfatal("pow(+0.0, -5.0) != HUGE_VAL");
29657718be8SEnji Cooper }
29757718be8SEnji Cooper
29857718be8SEnji Cooper z = pow(-0.0, -5.0);
29957718be8SEnji Cooper
30057718be8SEnji Cooper if (z != -HUGE_VAL)
30157718be8SEnji Cooper atf_tc_fail_nonfatal("pow(-0.0, -5.0) != -HUGE_VAL");
30257718be8SEnji Cooper }
30357718be8SEnji Cooper
30457718be8SEnji Cooper ATF_TC(pow_zero_y);
ATF_TC_HEAD(pow_zero_y,tc)30557718be8SEnji Cooper ATF_TC_HEAD(pow_zero_y, tc)
30657718be8SEnji Cooper {
30757718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0");
30857718be8SEnji Cooper }
30957718be8SEnji Cooper
ATF_TC_BODY(pow_zero_y,tc)31057718be8SEnji Cooper ATF_TC_BODY(pow_zero_y, tc)
31157718be8SEnji Cooper {
31257718be8SEnji Cooper const double x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
31357718be8SEnji Cooper const double z = 0.0L / 0.0L;
31457718be8SEnji Cooper size_t i;
31557718be8SEnji Cooper
31657718be8SEnji Cooper /*
31757718be8SEnji Cooper * For any value of x (including NaN),
31857718be8SEnji Cooper * if y is +0.0 or -0.0, 1.0 is returned.
31957718be8SEnji Cooper */
32057718be8SEnji Cooper if (pow(z, +0.0) != 1.0)
32157718be8SEnji Cooper atf_tc_fail_nonfatal("pow(NaN, +0.0) != 1.0");
32257718be8SEnji Cooper
32357718be8SEnji Cooper if (pow(z, -0.0) != 1.0)
32457718be8SEnji Cooper atf_tc_fail_nonfatal("pow(NaN, -0.0) != 1.0");
32557718be8SEnji Cooper
32657718be8SEnji Cooper for (i = 0; i < __arraycount(x); i++) {
32757718be8SEnji Cooper
32857718be8SEnji Cooper if (pow(x[i], +0.0) != 1.0)
32957718be8SEnji Cooper atf_tc_fail_nonfatal("pow(%0.01f, +0.0) != 1.0", x[i]);
33057718be8SEnji Cooper
33157718be8SEnji Cooper if (pow(x[i], -0.0) != 1.0)
33257718be8SEnji Cooper atf_tc_fail_nonfatal("pow(%0.01f, -0.0) != 1.0", x[i]);
33357718be8SEnji Cooper }
33457718be8SEnji Cooper }
33557718be8SEnji Cooper
33657718be8SEnji Cooper /*
33757718be8SEnji Cooper * powf(3)
33857718be8SEnji Cooper */
33957718be8SEnji Cooper ATF_TC(powf_nan_x);
ATF_TC_HEAD(powf_nan_x,tc)34057718be8SEnji Cooper ATF_TC_HEAD(powf_nan_x, tc)
34157718be8SEnji Cooper {
34257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN");
34357718be8SEnji Cooper }
34457718be8SEnji Cooper
ATF_TC_BODY(powf_nan_x,tc)34557718be8SEnji Cooper ATF_TC_BODY(powf_nan_x, tc)
34657718be8SEnji Cooper {
34757718be8SEnji Cooper const float x = 0.0L / 0.0L;
34857718be8SEnji Cooper
34957718be8SEnji Cooper ATF_CHECK(isnanf(powf(x, 2.0)) != 0);
35057718be8SEnji Cooper }
35157718be8SEnji Cooper
35257718be8SEnji Cooper ATF_TC(powf_nan_y);
ATF_TC_HEAD(powf_nan_y,tc)35357718be8SEnji Cooper ATF_TC_HEAD(powf_nan_y, tc)
35457718be8SEnji Cooper {
35557718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN");
35657718be8SEnji Cooper }
35757718be8SEnji Cooper
ATF_TC_BODY(powf_nan_y,tc)35857718be8SEnji Cooper ATF_TC_BODY(powf_nan_y, tc)
35957718be8SEnji Cooper {
36057718be8SEnji Cooper const float y = 0.0L / 0.0L;
36157718be8SEnji Cooper
36257718be8SEnji Cooper ATF_CHECK(isnanf(powf(2.0, y)) != 0);
36357718be8SEnji Cooper }
36457718be8SEnji Cooper
36557718be8SEnji Cooper ATF_TC(powf_inf_neg_x);
ATF_TC_HEAD(powf_inf_neg_x,tc)36657718be8SEnji Cooper ATF_TC_HEAD(powf_inf_neg_x, tc)
36757718be8SEnji Cooper {
36857718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0");
36957718be8SEnji Cooper }
37057718be8SEnji Cooper
ATF_TC_BODY(powf_inf_neg_x,tc)37157718be8SEnji Cooper ATF_TC_BODY(powf_inf_neg_x, tc)
37257718be8SEnji Cooper {
37357718be8SEnji Cooper const float x = -1.0L / 0.0L;
37457718be8SEnji Cooper float z;
37557718be8SEnji Cooper
37657718be8SEnji Cooper /*
37757718be8SEnji Cooper * If y is odd, y > 0, and x is -Inf, -Inf is returned.
37857718be8SEnji Cooper * If y is even, y > 0, and x is -Inf, +Inf is returned.
37957718be8SEnji Cooper */
38057718be8SEnji Cooper z = powf(x, 3.0);
38157718be8SEnji Cooper
382dd66b5baSEnji Cooper if (isinf(z) == 0 || signbit(z) == 0)
38357718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-Inf, 3.0) != -Inf");
38457718be8SEnji Cooper
38557718be8SEnji Cooper z = powf(x, 4.0);
38657718be8SEnji Cooper
387dd66b5baSEnji Cooper if (isinf(z) == 0 || signbit(z) != 0)
38857718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-Inf, 4.0) != +Inf");
38957718be8SEnji Cooper
39057718be8SEnji Cooper /*
39157718be8SEnji Cooper * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
39257718be8SEnji Cooper * If y is even, y < 0, and x is -Inf, +0.0 is returned.
39357718be8SEnji Cooper */
39457718be8SEnji Cooper z = powf(x, -3.0);
39557718be8SEnji Cooper
39657718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) == 0) {
39757718be8SEnji Cooper atf_tc_expect_fail("PR lib/45372");
39857718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-Inf, -3.0) != -0.0");
39957718be8SEnji Cooper }
40057718be8SEnji Cooper
40157718be8SEnji Cooper z = powf(x, -4.0);
40257718be8SEnji Cooper
40357718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) != 0)
40457718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-Inf -4.0) != +0.0");
40557718be8SEnji Cooper }
40657718be8SEnji Cooper
40757718be8SEnji Cooper ATF_TC(powf_inf_neg_y);
ATF_TC_HEAD(powf_inf_neg_y,tc)40857718be8SEnji Cooper ATF_TC_HEAD(powf_inf_neg_y, tc)
40957718be8SEnji Cooper {
41057718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0");
41157718be8SEnji Cooper }
41257718be8SEnji Cooper
ATF_TC_BODY(powf_inf_neg_y,tc)41357718be8SEnji Cooper ATF_TC_BODY(powf_inf_neg_y, tc)
41457718be8SEnji Cooper {
41557718be8SEnji Cooper const float y = -1.0L / 0.0L;
41657718be8SEnji Cooper float z;
41757718be8SEnji Cooper
41857718be8SEnji Cooper /*
41957718be8SEnji Cooper * If |x| < 1 and y is -Inf, +Inf is returned.
42057718be8SEnji Cooper * If |x| > 1 and y is -Inf, +0.0 is returned.
42157718be8SEnji Cooper */
42257718be8SEnji Cooper z = powf(0.1, y);
42357718be8SEnji Cooper
424dd66b5baSEnji Cooper if (isinf(z) == 0 || signbit(z) != 0)
42557718be8SEnji Cooper atf_tc_fail_nonfatal("powf(0.1, -Inf) != +Inf");
42657718be8SEnji Cooper
42757718be8SEnji Cooper z = powf(1.1, y);
42857718be8SEnji Cooper
42957718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) != 0)
43057718be8SEnji Cooper atf_tc_fail_nonfatal("powf(1.1, -Inf) != +0.0");
43157718be8SEnji Cooper }
43257718be8SEnji Cooper
43357718be8SEnji Cooper ATF_TC(powf_inf_pos_x);
ATF_TC_HEAD(powf_inf_pos_x,tc)43457718be8SEnji Cooper ATF_TC_HEAD(powf_inf_pos_x, tc)
43557718be8SEnji Cooper {
43657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0");
43757718be8SEnji Cooper }
43857718be8SEnji Cooper
ATF_TC_BODY(powf_inf_pos_x,tc)43957718be8SEnji Cooper ATF_TC_BODY(powf_inf_pos_x, tc)
44057718be8SEnji Cooper {
44157718be8SEnji Cooper const float x = 1.0L / 0.0L;
44257718be8SEnji Cooper float z;
44357718be8SEnji Cooper
44457718be8SEnji Cooper /*
44557718be8SEnji Cooper * For y < 0, if x is +Inf, +0.0 is returned.
44657718be8SEnji Cooper * For y > 0, if x is +Inf, +Inf is returned.
44757718be8SEnji Cooper */
44857718be8SEnji Cooper z = powf(x, -2.0);
44957718be8SEnji Cooper
45057718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) != 0)
45157718be8SEnji Cooper atf_tc_fail_nonfatal("powf(+Inf, -2.0) != +0.0");
45257718be8SEnji Cooper
45357718be8SEnji Cooper z = powf(x, 2.0);
45457718be8SEnji Cooper
455dd66b5baSEnji Cooper if (isinf(z) == 0 || signbit(z) != 0)
45657718be8SEnji Cooper atf_tc_fail_nonfatal("powf(+Inf, 2.0) != +Inf");
45757718be8SEnji Cooper }
45857718be8SEnji Cooper
45957718be8SEnji Cooper ATF_TC(powf_inf_pos_y);
ATF_TC_HEAD(powf_inf_pos_y,tc)46057718be8SEnji Cooper ATF_TC_HEAD(powf_inf_pos_y, tc)
46157718be8SEnji Cooper {
46257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0");
46357718be8SEnji Cooper }
46457718be8SEnji Cooper
ATF_TC_BODY(powf_inf_pos_y,tc)46557718be8SEnji Cooper ATF_TC_BODY(powf_inf_pos_y, tc)
46657718be8SEnji Cooper {
46757718be8SEnji Cooper const float y = 1.0L / 0.0L;
46857718be8SEnji Cooper float z;
46957718be8SEnji Cooper
47057718be8SEnji Cooper /*
47157718be8SEnji Cooper * If |x| < 1 and y is +Inf, +0.0 is returned.
47257718be8SEnji Cooper * If |x| > 1 and y is +Inf, +Inf is returned.
47357718be8SEnji Cooper */
47457718be8SEnji Cooper z = powf(0.1, y);
47557718be8SEnji Cooper
47657718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) != 0)
47757718be8SEnji Cooper atf_tc_fail_nonfatal("powf(0.1, +Inf) != +0.0");
47857718be8SEnji Cooper
47957718be8SEnji Cooper z = powf(1.1, y);
48057718be8SEnji Cooper
481dd66b5baSEnji Cooper if (isinf(z) == 0 || signbit(z) != 0)
48257718be8SEnji Cooper atf_tc_fail_nonfatal("powf(1.1, +Inf) != +Inf");
48357718be8SEnji Cooper }
48457718be8SEnji Cooper
48557718be8SEnji Cooper ATF_TC(powf_one_neg_x);
ATF_TC_HEAD(powf_one_neg_x,tc)48657718be8SEnji Cooper ATF_TC_HEAD(powf_one_neg_x, tc)
48757718be8SEnji Cooper {
48857718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0");
48957718be8SEnji Cooper }
49057718be8SEnji Cooper
ATF_TC_BODY(powf_one_neg_x,tc)49157718be8SEnji Cooper ATF_TC_BODY(powf_one_neg_x, tc)
49257718be8SEnji Cooper {
49357718be8SEnji Cooper const float infp = 1.0L / 0.0L;
49457718be8SEnji Cooper const float infn = -1.0L / 0.0L;
49557718be8SEnji Cooper
49657718be8SEnji Cooper /*
49757718be8SEnji Cooper * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
49857718be8SEnji Cooper */
499dd66b5baSEnji Cooper ATF_REQUIRE(isinf(infp) != 0);
500dd66b5baSEnji Cooper ATF_REQUIRE(isinf(infn) != 0);
50157718be8SEnji Cooper
50257718be8SEnji Cooper if (powf(-1.0, infp) != 1.0) {
50357718be8SEnji Cooper atf_tc_expect_fail("PR lib/45372");
50457718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-1.0, +Inf) != 1.0");
50557718be8SEnji Cooper }
50657718be8SEnji Cooper
50757718be8SEnji Cooper if (powf(-1.0, infn) != 1.0) {
50857718be8SEnji Cooper atf_tc_expect_fail("PR lib/45372");
50957718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-1.0, -Inf) != 1.0");
51057718be8SEnji Cooper }
51157718be8SEnji Cooper }
51257718be8SEnji Cooper
51357718be8SEnji Cooper ATF_TC(powf_one_pos_x);
ATF_TC_HEAD(powf_one_pos_x,tc)51457718be8SEnji Cooper ATF_TC_HEAD(powf_one_pos_x, tc)
51557718be8SEnji Cooper {
51657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0");
51757718be8SEnji Cooper }
51857718be8SEnji Cooper
ATF_TC_BODY(powf_one_pos_x,tc)51957718be8SEnji Cooper ATF_TC_BODY(powf_one_pos_x, tc)
52057718be8SEnji Cooper {
52157718be8SEnji Cooper const float y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
52257718be8SEnji Cooper const float z = 0.0L / 0.0L;
52357718be8SEnji Cooper size_t i;
52457718be8SEnji Cooper
52557718be8SEnji Cooper /*
52657718be8SEnji Cooper * For any value of y (including NaN),
52757718be8SEnji Cooper * if x is 1.0, 1.0 shall be returned.
52857718be8SEnji Cooper */
52957718be8SEnji Cooper if (powf(1.0, z) != 1.0)
53057718be8SEnji Cooper atf_tc_fail_nonfatal("powf(1.0, NaN) != 1.0");
53157718be8SEnji Cooper
53257718be8SEnji Cooper for (i = 0; i < __arraycount(y); i++) {
53357718be8SEnji Cooper
53457718be8SEnji Cooper if (powf(1.0, y[i]) != 1.0)
53557718be8SEnji Cooper atf_tc_fail_nonfatal("powf(1.0, %0.01f) != 1.0", y[i]);
53657718be8SEnji Cooper }
53757718be8SEnji Cooper }
53857718be8SEnji Cooper
53957718be8SEnji Cooper ATF_TC(powf_zero_x);
ATF_TC_HEAD(powf_zero_x,tc)54057718be8SEnji Cooper ATF_TC_HEAD(powf_zero_x, tc)
54157718be8SEnji Cooper {
54257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE");
54357718be8SEnji Cooper }
54457718be8SEnji Cooper
ATF_TC_BODY(powf_zero_x,tc)54557718be8SEnji Cooper ATF_TC_BODY(powf_zero_x, tc)
54657718be8SEnji Cooper {
54757718be8SEnji Cooper float z;
54857718be8SEnji Cooper
54957718be8SEnji Cooper /*
55057718be8SEnji Cooper * If x is +0.0 or -0.0, y > 0, and y
55157718be8SEnji Cooper * is an odd integer, x is returned.
55257718be8SEnji Cooper */
55357718be8SEnji Cooper z = powf(+0.0, 3.0);
55457718be8SEnji Cooper
55557718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) != 0)
55657718be8SEnji Cooper atf_tc_fail_nonfatal("powf(+0.0, 3.0) != +0.0");
55757718be8SEnji Cooper
55857718be8SEnji Cooper z = powf(-0.0, 3.0);
55957718be8SEnji Cooper
56057718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) == 0)
56157718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-0.0, 3.0) != -0.0");
56257718be8SEnji Cooper
56357718be8SEnji Cooper /*
56457718be8SEnji Cooper * If y > 0 and not an odd integer,
56557718be8SEnji Cooper * if x is +0.0 or -0.0, +0.0 is returned.
56657718be8SEnji Cooper */
56757718be8SEnji Cooper z = powf(+0.0, 4.0);
56857718be8SEnji Cooper
56957718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) != 0)
57057718be8SEnji Cooper atf_tc_fail_nonfatal("powf(+0.0, 4.0) != +0.0");
57157718be8SEnji Cooper
57257718be8SEnji Cooper z = powf(-0.0, 4.0);
57357718be8SEnji Cooper
57457718be8SEnji Cooper if (fabsf(z) > 0.0 || signbit(z) != 0)
57557718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-0.0, 4.0) != +0.0");
57657718be8SEnji Cooper
57757718be8SEnji Cooper /*
57857718be8SEnji Cooper * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
57957718be8SEnji Cooper * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
58057718be8SEnji Cooper */
58157718be8SEnji Cooper z = powf(+0.0, -4.0);
58257718be8SEnji Cooper
58357718be8SEnji Cooper if (z != HUGE_VALF) {
58457718be8SEnji Cooper atf_tc_expect_fail("PR port-amd64/45391");
58557718be8SEnji Cooper atf_tc_fail_nonfatal("powf(+0.0, -4.0) != HUGE_VALF");
58657718be8SEnji Cooper }
58757718be8SEnji Cooper
58857718be8SEnji Cooper z = powf(-0.0, -4.0);
58957718be8SEnji Cooper
59057718be8SEnji Cooper if (z != HUGE_VALF) {
59157718be8SEnji Cooper atf_tc_expect_fail("PR port-amd64/45391");
59257718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-0.0, -4.0) != HUGE_VALF");
59357718be8SEnji Cooper }
59457718be8SEnji Cooper
59557718be8SEnji Cooper z = powf(+0.0, -5.0);
59657718be8SEnji Cooper
59757718be8SEnji Cooper if (z != HUGE_VALF) {
59857718be8SEnji Cooper atf_tc_expect_fail("PR port-amd64/45391");
59957718be8SEnji Cooper atf_tc_fail_nonfatal("powf(+0.0, -5.0) != HUGE_VALF");
60057718be8SEnji Cooper }
60157718be8SEnji Cooper
60257718be8SEnji Cooper z = powf(-0.0, -5.0);
60357718be8SEnji Cooper
60457718be8SEnji Cooper if (z != -HUGE_VALF)
60557718be8SEnji Cooper atf_tc_fail_nonfatal("powf(-0.0, -5.0) != -HUGE_VALF");
60657718be8SEnji Cooper }
60757718be8SEnji Cooper
60857718be8SEnji Cooper ATF_TC(powf_zero_y);
ATF_TC_HEAD(powf_zero_y,tc)60957718be8SEnji Cooper ATF_TC_HEAD(powf_zero_y, tc)
61057718be8SEnji Cooper {
61157718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0");
61257718be8SEnji Cooper }
61357718be8SEnji Cooper
ATF_TC_BODY(powf_zero_y,tc)61457718be8SEnji Cooper ATF_TC_BODY(powf_zero_y, tc)
61557718be8SEnji Cooper {
61657718be8SEnji Cooper const float x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
61757718be8SEnji Cooper const float z = 0.0L / 0.0L;
61857718be8SEnji Cooper size_t i;
61957718be8SEnji Cooper
62057718be8SEnji Cooper /*
62157718be8SEnji Cooper * For any value of x (including NaN),
62257718be8SEnji Cooper * if y is +0.0 or -0.0, 1.0 is returned.
62357718be8SEnji Cooper */
62457718be8SEnji Cooper if (powf(z, +0.0) != 1.0)
62557718be8SEnji Cooper atf_tc_fail_nonfatal("powf(NaN, +0.0) != 1.0");
62657718be8SEnji Cooper
62757718be8SEnji Cooper if (powf(z, -0.0) != 1.0)
62857718be8SEnji Cooper atf_tc_fail_nonfatal("powf(NaN, -0.0) != 1.0");
62957718be8SEnji Cooper
63057718be8SEnji Cooper for (i = 0; i < __arraycount(x); i++) {
63157718be8SEnji Cooper
63257718be8SEnji Cooper if (powf(x[i], +0.0) != 1.0)
63357718be8SEnji Cooper atf_tc_fail_nonfatal("powf(%0.01f, +0.0) != 1.0",x[i]);
63457718be8SEnji Cooper
63557718be8SEnji Cooper if (powf(x[i], -0.0) != 1.0)
63657718be8SEnji Cooper atf_tc_fail_nonfatal("powf(%0.01f, -0.0) != 1.0",x[i]);
63757718be8SEnji Cooper }
63857718be8SEnji Cooper }
63957718be8SEnji Cooper
640*51af0332SDimitry Andric ATF_TC(powf_near_one_x_huge_y);
ATF_TC_HEAD(powf_near_one_x_huge_y,tc)641*51af0332SDimitry Andric ATF_TC_HEAD(powf_near_one_x_huge_y, tc)
642*51af0332SDimitry Andric {
643*51af0332SDimitry Andric atf_tc_set_md_var(tc, "descr", "Test powf(->1, huge) != inf");
644*51af0332SDimitry Andric }
645*51af0332SDimitry Andric
ATF_TC_BODY(powf_near_one_x_huge_y,tc)646*51af0332SDimitry Andric ATF_TC_BODY(powf_near_one_x_huge_y, tc)
647*51af0332SDimitry Andric {
648*51af0332SDimitry Andric const float x = 0x1.ffffeep-1f; /* 9.999995e-01f */
649*51af0332SDimitry Andric const float y = -0x1.000002p+27f; /* -1.342177e+08f */
650*51af0332SDimitry Andric const float e = 0x1.d53532p+103f; /* 1.858724e+31f */
651*51af0332SDimitry Andric const float ulp = __FLT_EPSILON__;
652*51af0332SDimitry Andric float z;
653*51af0332SDimitry Andric
654*51af0332SDimitry Andric z = powf(x, y);
655*51af0332SDimitry Andric
656*51af0332SDimitry Andric ATF_CHECK(isinf(z) == 0);
657*51af0332SDimitry Andric ATF_CHECK(fabsf(z - e) <= 2 * ulp);
658*51af0332SDimitry Andric }
659*51af0332SDimitry Andric
660*51af0332SDimitry Andric
ATF_TP_ADD_TCS(tp)66157718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
66257718be8SEnji Cooper {
66357718be8SEnji Cooper
66457718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_nan_x);
66557718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_nan_y);
66657718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_inf_neg_x);
66757718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_inf_neg_y);
66857718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_inf_pos_x);
66957718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_inf_pos_y);
67057718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_one_neg_x);
67157718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_one_pos_x);
67257718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_zero_x);
67357718be8SEnji Cooper ATF_TP_ADD_TC(tp, pow_zero_y);
67457718be8SEnji Cooper
67557718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_nan_x);
67657718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_nan_y);
67757718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_inf_neg_x);
67857718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_inf_neg_y);
67957718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_inf_pos_x);
68057718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_inf_pos_y);
68157718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_one_neg_x);
68257718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_one_pos_x);
68357718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_zero_x);
68457718be8SEnji Cooper ATF_TP_ADD_TC(tp, powf_zero_y);
685*51af0332SDimitry Andric ATF_TP_ADD_TC(tp, powf_near_one_x_huge_y);
68657718be8SEnji Cooper
68757718be8SEnji Cooper return atf_no_error();
68857718be8SEnji Cooper }
689