t_pow.c revision 272343
1272343Sngie/* $NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */
2272343Sngie
3272343Sngie/*-
4272343Sngie * Copyright (c) 2011 The NetBSD Foundation, Inc.
5272343Sngie * All rights reserved.
6272343Sngie *
7272343Sngie * This code is derived from software contributed to The NetBSD Foundation
8272343Sngie * by Jukka Ruohonen.
9272343Sngie *
10272343Sngie * Redistribution and use in source and binary forms, with or without
11272343Sngie * modification, are permitted provided that the following conditions
12272343Sngie * are met:
13272343Sngie * 1. Redistributions of source code must retain the above copyright
14272343Sngie *    notice, this list of conditions and the following disclaimer.
15272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
16272343Sngie *    notice, this list of conditions and the following disclaimer in the
17272343Sngie *    documentation and/or other materials provided with the distribution.
18272343Sngie *
19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22272343Sngie * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29272343Sngie * POSSIBILITY OF SUCH DAMAGE.
30272343Sngie */
31272343Sngie#include <sys/cdefs.h>
32272343Sngie__RCSID("$NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $");
33272343Sngie
34272343Sngie#include <atf-c.h>
35272343Sngie#include <math.h>
36272343Sngie
37272343Sngie/*
38272343Sngie * pow(3)
39272343Sngie */
40272343SngieATF_TC(pow_nan_x);
41272343SngieATF_TC_HEAD(pow_nan_x, tc)
42272343Sngie{
43272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN");
44272343Sngie}
45272343Sngie
46272343SngieATF_TC_BODY(pow_nan_x, tc)
47272343Sngie{
48272343Sngie	const double x = 0.0L / 0.0L;
49272343Sngie
50272343Sngie	ATF_CHECK(isnan(pow(x, 2.0)) != 0);
51272343Sngie}
52272343Sngie
53272343SngieATF_TC(pow_nan_y);
54272343SngieATF_TC_HEAD(pow_nan_y, tc)
55272343Sngie{
56272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN");
57272343Sngie}
58272343Sngie
59272343SngieATF_TC_BODY(pow_nan_y, tc)
60272343Sngie{
61272343Sngie	const double y = 0.0L / 0.0L;
62272343Sngie
63272343Sngie	ATF_CHECK(isnan(pow(2.0, y)) != 0);
64272343Sngie}
65272343Sngie
66272343SngieATF_TC(pow_inf_neg_x);
67272343SngieATF_TC_HEAD(pow_inf_neg_x, tc)
68272343Sngie{
69272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0");
70272343Sngie}
71272343Sngie
72272343SngieATF_TC_BODY(pow_inf_neg_x, tc)
73272343Sngie{
74272343Sngie	const double x = -1.0L / 0.0L;
75272343Sngie	double z;
76272343Sngie
77272343Sngie	/*
78272343Sngie	 * If y is odd, y > 0, and x is -Inf, -Inf is returned.
79272343Sngie	 * If y is even, y > 0, and x is -Inf, +Inf is returned.
80272343Sngie	 */
81272343Sngie	z = pow(x, 3.0);
82272343Sngie
83272343Sngie	if (isinf(z) == 0 || signbit(z) == 0)
84272343Sngie		atf_tc_fail_nonfatal("pow(-Inf, 3.0) != -Inf");
85272343Sngie
86272343Sngie	z = pow(x, 4.0);
87272343Sngie
88272343Sngie	if (isinf(z) == 0 || signbit(z) != 0)
89272343Sngie		atf_tc_fail_nonfatal("pow(-Inf, 4.0) != +Inf");
90272343Sngie
91272343Sngie	/*
92272343Sngie	 * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
93272343Sngie	 * If y is even, y < 0, and x is -Inf, +0.0 is returned.
94272343Sngie	 */
95272343Sngie	z = pow(x, -3.0);
96272343Sngie
97272343Sngie	if (fabs(z) > 0.0 || signbit(z) == 0)
98272343Sngie		atf_tc_fail_nonfatal("pow(-Inf, -3.0) != -0.0");
99272343Sngie
100272343Sngie	z = pow(x, -4.0);
101272343Sngie
102272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
103272343Sngie		atf_tc_fail_nonfatal("pow(-Inf -4.0) != +0.0");
104272343Sngie}
105272343Sngie
106272343SngieATF_TC(pow_inf_neg_y);
107272343SngieATF_TC_HEAD(pow_inf_neg_y, tc)
108272343Sngie{
109272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0");
110272343Sngie}
111272343Sngie
112272343SngieATF_TC_BODY(pow_inf_neg_y, tc)
113272343Sngie{
114272343Sngie	const double y = -1.0L / 0.0L;
115272343Sngie	double z;
116272343Sngie
117272343Sngie	/*
118272343Sngie	 * If |x| < 1 and y is -Inf, +Inf is returned.
119272343Sngie	 * If |x| > 1 and y is -Inf, +0.0 is returned.
120272343Sngie	 */
121272343Sngie	z = pow(0.1, y);
122272343Sngie
123272343Sngie	if (isinf(z) == 0 || signbit(z) != 0)
124272343Sngie		atf_tc_fail_nonfatal("pow(0.1, -Inf) != +Inf");
125272343Sngie
126272343Sngie	z = pow(1.1, y);
127272343Sngie
128272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
129272343Sngie		atf_tc_fail_nonfatal("pow(1.1, -Inf) != +0.0");
130272343Sngie}
131272343Sngie
132272343SngieATF_TC(pow_inf_pos_x);
133272343SngieATF_TC_HEAD(pow_inf_pos_x, tc)
134272343Sngie{
135272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0");
136272343Sngie}
137272343Sngie
138272343SngieATF_TC_BODY(pow_inf_pos_x, tc)
139272343Sngie{
140272343Sngie	const double x = 1.0L / 0.0L;
141272343Sngie	double z;
142272343Sngie
143272343Sngie	/*
144272343Sngie	 * For y < 0, if x is +Inf, +0.0 is returned.
145272343Sngie	 * For y > 0, if x is +Inf, +Inf is returned.
146272343Sngie	 */
147272343Sngie	z = pow(x, -2.0);
148272343Sngie
149272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
150272343Sngie		atf_tc_fail_nonfatal("pow(+Inf, -2.0) != +0.0");
151272343Sngie
152272343Sngie	z = pow(x, 2.0);
153272343Sngie
154272343Sngie	if (isinf(z) == 0 || signbit(z) != 0)
155272343Sngie		atf_tc_fail_nonfatal("pow(+Inf, 2.0) != +Inf");
156272343Sngie}
157272343Sngie
158272343SngieATF_TC(pow_inf_pos_y);
159272343SngieATF_TC_HEAD(pow_inf_pos_y, tc)
160272343Sngie{
161272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0");
162272343Sngie}
163272343Sngie
164272343SngieATF_TC_BODY(pow_inf_pos_y, tc)
165272343Sngie{
166272343Sngie	const double y = 1.0L / 0.0L;
167272343Sngie	double z;
168272343Sngie
169272343Sngie	/*
170272343Sngie	 * If |x| < 1 and y is +Inf, +0.0 is returned.
171272343Sngie	 * If |x| > 1 and y is +Inf, +Inf is returned.
172272343Sngie	 */
173272343Sngie	z = pow(0.1, y);
174272343Sngie
175272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
176272343Sngie		atf_tc_fail_nonfatal("pow(0.1, +Inf) != +0.0");
177272343Sngie
178272343Sngie	z = pow(1.1, y);
179272343Sngie
180272343Sngie	if (isinf(z) == 0 || signbit(z) != 0)
181272343Sngie		atf_tc_fail_nonfatal("pow(1.1, +Inf) != +Inf");
182272343Sngie}
183272343Sngie
184272343SngieATF_TC(pow_one_neg_x);
185272343SngieATF_TC_HEAD(pow_one_neg_x, tc)
186272343Sngie{
187272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0");
188272343Sngie}
189272343Sngie
190272343SngieATF_TC_BODY(pow_one_neg_x, tc)
191272343Sngie{
192272343Sngie	const double infp = 1.0L / 0.0L;
193272343Sngie	const double infn = -1.0L / 0.0L;
194272343Sngie
195272343Sngie	/*
196272343Sngie	 * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
197272343Sngie	 */
198272343Sngie	ATF_REQUIRE(isinf(infp) != 0);
199272343Sngie	ATF_REQUIRE(isinf(infn) != 0);
200272343Sngie
201272343Sngie	if (pow(-1.0, infp) != 1.0) {
202272343Sngie		atf_tc_expect_fail("PR lib/45372");
203272343Sngie		atf_tc_fail_nonfatal("pow(-1.0, +Inf) != 1.0");
204272343Sngie	}
205272343Sngie
206272343Sngie	if (pow(-1.0, infn) != 1.0) {
207272343Sngie		atf_tc_expect_fail("PR lib/45372");
208272343Sngie		atf_tc_fail_nonfatal("pow(-1.0, -Inf) != 1.0");
209272343Sngie	}
210272343Sngie}
211272343Sngie
212272343SngieATF_TC(pow_one_pos_x);
213272343SngieATF_TC_HEAD(pow_one_pos_x, tc)
214272343Sngie{
215272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0");
216272343Sngie}
217272343Sngie
218272343SngieATF_TC_BODY(pow_one_pos_x, tc)
219272343Sngie{
220272343Sngie	const double y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
221272343Sngie	const double z = 0.0L / 0.0L;
222272343Sngie	size_t i;
223272343Sngie
224272343Sngie	/*
225272343Sngie	 * For any value of y (including NaN),
226272343Sngie	 * if x is 1.0, 1.0 shall be returned.
227272343Sngie	 */
228272343Sngie	if (pow(1.0, z) != 1.0)
229272343Sngie		atf_tc_fail_nonfatal("pow(1.0, NaN) != 1.0");
230272343Sngie
231272343Sngie	for (i = 0; i < __arraycount(y); i++) {
232272343Sngie
233272343Sngie		if (pow(1.0, y[i]) != 1.0)
234272343Sngie			atf_tc_fail_nonfatal("pow(1.0, %0.01f) != 1.0", y[i]);
235272343Sngie	}
236272343Sngie}
237272343Sngie
238272343SngieATF_TC(pow_zero_x);
239272343SngieATF_TC_HEAD(pow_zero_x, tc)
240272343Sngie{
241272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE");
242272343Sngie}
243272343Sngie
244272343SngieATF_TC_BODY(pow_zero_x, tc)
245272343Sngie{
246272343Sngie	double z;
247272343Sngie
248272343Sngie	/*
249272343Sngie	 * If x is +0.0 or -0.0, y > 0, and y
250272343Sngie	 * is an odd integer, x is returned.
251272343Sngie	 */
252272343Sngie	z = pow(+0.0, 3.0);
253272343Sngie
254272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
255272343Sngie		atf_tc_fail_nonfatal("pow(+0.0, 3.0) != +0.0");
256272343Sngie
257272343Sngie	z = pow(-0.0, 3.0);
258272343Sngie
259272343Sngie	if (fabs(z) > 0.0 || signbit(z) == 0)
260272343Sngie		atf_tc_fail_nonfatal("pow(-0.0, 3.0) != -0.0");
261272343Sngie
262272343Sngie	/*
263272343Sngie	 * If y > 0 and not an odd integer,
264272343Sngie	 * if x is +0.0 or -0.0, +0.0 is returned.
265272343Sngie	 */
266272343Sngie	z = pow(+0.0, 4.0);
267272343Sngie
268272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
269272343Sngie		atf_tc_fail_nonfatal("pow(+0.0, 4.0) != +0.0");
270272343Sngie
271272343Sngie	z = pow(-0.0, 4.0);
272272343Sngie
273272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
274272343Sngie		atf_tc_fail_nonfatal("pow(-0.0, 4.0) != +0.0");
275272343Sngie
276272343Sngie	/*
277272343Sngie	 * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
278272343Sngie	 * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
279272343Sngie	 */
280272343Sngie	z = pow(+0.0, -4.0);
281272343Sngie
282272343Sngie	if (z != HUGE_VAL) {
283272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
284272343Sngie		atf_tc_fail_nonfatal("pow(+0.0, -4.0) != HUGE_VAL");
285272343Sngie	}
286272343Sngie
287272343Sngie	z = pow(-0.0, -4.0);
288272343Sngie
289272343Sngie	if (z != HUGE_VAL) {
290272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
291272343Sngie		atf_tc_fail_nonfatal("pow(-0.0, -4.0) != HUGE_VAL");
292272343Sngie	}
293272343Sngie
294272343Sngie	z = pow(+0.0, -5.0);
295272343Sngie
296272343Sngie	if (z != HUGE_VAL) {
297272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
298272343Sngie		atf_tc_fail_nonfatal("pow(+0.0, -5.0) != HUGE_VAL");
299272343Sngie	}
300272343Sngie
301272343Sngie	z = pow(-0.0, -5.0);
302272343Sngie
303272343Sngie	if (z != -HUGE_VAL)
304272343Sngie		atf_tc_fail_nonfatal("pow(-0.0, -5.0) != -HUGE_VAL");
305272343Sngie}
306272343Sngie
307272343SngieATF_TC(pow_zero_y);
308272343SngieATF_TC_HEAD(pow_zero_y, tc)
309272343Sngie{
310272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0");
311272343Sngie}
312272343Sngie
313272343SngieATF_TC_BODY(pow_zero_y, tc)
314272343Sngie{
315272343Sngie	const double x[] =  { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
316272343Sngie	const double z = 0.0L / 0.0L;
317272343Sngie	size_t i;
318272343Sngie
319272343Sngie	/*
320272343Sngie	 * For any value of x (including NaN),
321272343Sngie	 * if y is +0.0 or -0.0, 1.0 is returned.
322272343Sngie	 */
323272343Sngie	if (pow(z, +0.0) != 1.0)
324272343Sngie		atf_tc_fail_nonfatal("pow(NaN, +0.0) != 1.0");
325272343Sngie
326272343Sngie	if (pow(z, -0.0) != 1.0)
327272343Sngie		atf_tc_fail_nonfatal("pow(NaN, -0.0) != 1.0");
328272343Sngie
329272343Sngie	for (i = 0; i < __arraycount(x); i++) {
330272343Sngie
331272343Sngie		if (pow(x[i], +0.0) != 1.0)
332272343Sngie			atf_tc_fail_nonfatal("pow(%0.01f, +0.0) != 1.0", x[i]);
333272343Sngie
334272343Sngie		if (pow(x[i], -0.0) != 1.0)
335272343Sngie			atf_tc_fail_nonfatal("pow(%0.01f, -0.0) != 1.0", x[i]);
336272343Sngie	}
337272343Sngie}
338272343Sngie
339272343Sngie/*
340272343Sngie * powf(3)
341272343Sngie */
342272343SngieATF_TC(powf_nan_x);
343272343SngieATF_TC_HEAD(powf_nan_x, tc)
344272343Sngie{
345272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN");
346272343Sngie}
347272343Sngie
348272343SngieATF_TC_BODY(powf_nan_x, tc)
349272343Sngie{
350272343Sngie	const float x = 0.0L / 0.0L;
351272343Sngie
352272343Sngie	ATF_CHECK(isnanf(powf(x, 2.0)) != 0);
353272343Sngie}
354272343Sngie
355272343SngieATF_TC(powf_nan_y);
356272343SngieATF_TC_HEAD(powf_nan_y, tc)
357272343Sngie{
358272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN");
359272343Sngie}
360272343Sngie
361272343SngieATF_TC_BODY(powf_nan_y, tc)
362272343Sngie{
363272343Sngie	const float y = 0.0L / 0.0L;
364272343Sngie
365272343Sngie	ATF_CHECK(isnanf(powf(2.0, y)) != 0);
366272343Sngie}
367272343Sngie
368272343SngieATF_TC(powf_inf_neg_x);
369272343SngieATF_TC_HEAD(powf_inf_neg_x, tc)
370272343Sngie{
371272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0");
372272343Sngie}
373272343Sngie
374272343SngieATF_TC_BODY(powf_inf_neg_x, tc)
375272343Sngie{
376272343Sngie	const float x = -1.0L / 0.0L;
377272343Sngie	float z;
378272343Sngie
379272343Sngie	/*
380272343Sngie	 * If y is odd, y > 0, and x is -Inf, -Inf is returned.
381272343Sngie	 * If y is even, y > 0, and x is -Inf, +Inf is returned.
382272343Sngie	 */
383272343Sngie	z = powf(x, 3.0);
384272343Sngie
385272343Sngie	if (isinff(z) == 0 || signbit(z) == 0)
386272343Sngie		atf_tc_fail_nonfatal("powf(-Inf, 3.0) != -Inf");
387272343Sngie
388272343Sngie	z = powf(x, 4.0);
389272343Sngie
390272343Sngie	if (isinff(z) == 0 || signbit(z) != 0)
391272343Sngie		atf_tc_fail_nonfatal("powf(-Inf, 4.0) != +Inf");
392272343Sngie
393272343Sngie	/*
394272343Sngie	 * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
395272343Sngie	 * If y is even, y < 0, and x is -Inf, +0.0 is returned.
396272343Sngie	 */
397272343Sngie	z = powf(x, -3.0);
398272343Sngie
399272343Sngie	if (fabsf(z) > 0.0 || signbit(z) == 0) {
400272343Sngie		atf_tc_expect_fail("PR lib/45372");
401272343Sngie		atf_tc_fail_nonfatal("powf(-Inf, -3.0) != -0.0");
402272343Sngie	}
403272343Sngie
404272343Sngie	z = powf(x, -4.0);
405272343Sngie
406272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
407272343Sngie		atf_tc_fail_nonfatal("powf(-Inf -4.0) != +0.0");
408272343Sngie}
409272343Sngie
410272343SngieATF_TC(powf_inf_neg_y);
411272343SngieATF_TC_HEAD(powf_inf_neg_y, tc)
412272343Sngie{
413272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0");
414272343Sngie}
415272343Sngie
416272343SngieATF_TC_BODY(powf_inf_neg_y, tc)
417272343Sngie{
418272343Sngie	const float y = -1.0L / 0.0L;
419272343Sngie	float z;
420272343Sngie
421272343Sngie	/*
422272343Sngie	 * If |x| < 1 and y is -Inf, +Inf is returned.
423272343Sngie	 * If |x| > 1 and y is -Inf, +0.0 is returned.
424272343Sngie	 */
425272343Sngie	z = powf(0.1, y);
426272343Sngie
427272343Sngie	if (isinff(z) == 0 || signbit(z) != 0)
428272343Sngie		atf_tc_fail_nonfatal("powf(0.1, -Inf) != +Inf");
429272343Sngie
430272343Sngie	z = powf(1.1, y);
431272343Sngie
432272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
433272343Sngie		atf_tc_fail_nonfatal("powf(1.1, -Inf) != +0.0");
434272343Sngie}
435272343Sngie
436272343SngieATF_TC(powf_inf_pos_x);
437272343SngieATF_TC_HEAD(powf_inf_pos_x, tc)
438272343Sngie{
439272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0");
440272343Sngie}
441272343Sngie
442272343SngieATF_TC_BODY(powf_inf_pos_x, tc)
443272343Sngie{
444272343Sngie	const float x = 1.0L / 0.0L;
445272343Sngie	float z;
446272343Sngie
447272343Sngie	/*
448272343Sngie	 * For y < 0, if x is +Inf, +0.0 is returned.
449272343Sngie	 * For y > 0, if x is +Inf, +Inf is returned.
450272343Sngie	 */
451272343Sngie	z = powf(x, -2.0);
452272343Sngie
453272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
454272343Sngie		atf_tc_fail_nonfatal("powf(+Inf, -2.0) != +0.0");
455272343Sngie
456272343Sngie	z = powf(x, 2.0);
457272343Sngie
458272343Sngie	if (isinff(z) == 0 || signbit(z) != 0)
459272343Sngie		atf_tc_fail_nonfatal("powf(+Inf, 2.0) != +Inf");
460272343Sngie}
461272343Sngie
462272343SngieATF_TC(powf_inf_pos_y);
463272343SngieATF_TC_HEAD(powf_inf_pos_y, tc)
464272343Sngie{
465272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0");
466272343Sngie}
467272343Sngie
468272343SngieATF_TC_BODY(powf_inf_pos_y, tc)
469272343Sngie{
470272343Sngie	const float y = 1.0L / 0.0L;
471272343Sngie	float z;
472272343Sngie
473272343Sngie	/*
474272343Sngie	 * If |x| < 1 and y is +Inf, +0.0 is returned.
475272343Sngie	 * If |x| > 1 and y is +Inf, +Inf is returned.
476272343Sngie	 */
477272343Sngie	z = powf(0.1, y);
478272343Sngie
479272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
480272343Sngie		atf_tc_fail_nonfatal("powf(0.1, +Inf) != +0.0");
481272343Sngie
482272343Sngie	z = powf(1.1, y);
483272343Sngie
484272343Sngie	if (isinff(z) == 0 || signbit(z) != 0)
485272343Sngie		atf_tc_fail_nonfatal("powf(1.1, +Inf) != +Inf");
486272343Sngie}
487272343Sngie
488272343SngieATF_TC(powf_one_neg_x);
489272343SngieATF_TC_HEAD(powf_one_neg_x, tc)
490272343Sngie{
491272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0");
492272343Sngie}
493272343Sngie
494272343SngieATF_TC_BODY(powf_one_neg_x, tc)
495272343Sngie{
496272343Sngie	const float infp = 1.0L / 0.0L;
497272343Sngie	const float infn = -1.0L / 0.0L;
498272343Sngie
499272343Sngie	/*
500272343Sngie	 * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
501272343Sngie	 */
502272343Sngie	ATF_REQUIRE(isinff(infp) != 0);
503272343Sngie	ATF_REQUIRE(isinff(infn) != 0);
504272343Sngie
505272343Sngie	if (powf(-1.0, infp) != 1.0) {
506272343Sngie		atf_tc_expect_fail("PR lib/45372");
507272343Sngie		atf_tc_fail_nonfatal("powf(-1.0, +Inf) != 1.0");
508272343Sngie	}
509272343Sngie
510272343Sngie	if (powf(-1.0, infn) != 1.0) {
511272343Sngie		atf_tc_expect_fail("PR lib/45372");
512272343Sngie		atf_tc_fail_nonfatal("powf(-1.0, -Inf) != 1.0");
513272343Sngie	}
514272343Sngie}
515272343Sngie
516272343SngieATF_TC(powf_one_pos_x);
517272343SngieATF_TC_HEAD(powf_one_pos_x, tc)
518272343Sngie{
519272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0");
520272343Sngie}
521272343Sngie
522272343SngieATF_TC_BODY(powf_one_pos_x, tc)
523272343Sngie{
524272343Sngie	const float y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
525272343Sngie	const float z = 0.0L / 0.0L;
526272343Sngie	size_t i;
527272343Sngie
528272343Sngie	/*
529272343Sngie	 * For any value of y (including NaN),
530272343Sngie	 * if x is 1.0, 1.0 shall be returned.
531272343Sngie	 */
532272343Sngie	if (powf(1.0, z) != 1.0)
533272343Sngie		atf_tc_fail_nonfatal("powf(1.0, NaN) != 1.0");
534272343Sngie
535272343Sngie	for (i = 0; i < __arraycount(y); i++) {
536272343Sngie
537272343Sngie		if (powf(1.0, y[i]) != 1.0)
538272343Sngie			atf_tc_fail_nonfatal("powf(1.0, %0.01f) != 1.0", y[i]);
539272343Sngie	}
540272343Sngie}
541272343Sngie
542272343SngieATF_TC(powf_zero_x);
543272343SngieATF_TC_HEAD(powf_zero_x, tc)
544272343Sngie{
545272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE");
546272343Sngie}
547272343Sngie
548272343SngieATF_TC_BODY(powf_zero_x, tc)
549272343Sngie{
550272343Sngie	float z;
551272343Sngie
552272343Sngie	/*
553272343Sngie	 * If x is +0.0 or -0.0, y > 0, and y
554272343Sngie	 * is an odd integer, x is returned.
555272343Sngie	 */
556272343Sngie	z = powf(+0.0, 3.0);
557272343Sngie
558272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
559272343Sngie		atf_tc_fail_nonfatal("powf(+0.0, 3.0) != +0.0");
560272343Sngie
561272343Sngie	z = powf(-0.0, 3.0);
562272343Sngie
563272343Sngie	if (fabsf(z) > 0.0 || signbit(z) == 0)
564272343Sngie		atf_tc_fail_nonfatal("powf(-0.0, 3.0) != -0.0");
565272343Sngie
566272343Sngie	/*
567272343Sngie	 * If y > 0 and not an odd integer,
568272343Sngie	 * if x is +0.0 or -0.0, +0.0 is returned.
569272343Sngie	 */
570272343Sngie	z = powf(+0.0, 4.0);
571272343Sngie
572272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
573272343Sngie		atf_tc_fail_nonfatal("powf(+0.0, 4.0) != +0.0");
574272343Sngie
575272343Sngie	z = powf(-0.0, 4.0);
576272343Sngie
577272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
578272343Sngie		atf_tc_fail_nonfatal("powf(-0.0, 4.0) != +0.0");
579272343Sngie
580272343Sngie	/*
581272343Sngie	 * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
582272343Sngie	 * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
583272343Sngie	 */
584272343Sngie	z = powf(+0.0, -4.0);
585272343Sngie
586272343Sngie	if (z != HUGE_VALF) {
587272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
588272343Sngie		atf_tc_fail_nonfatal("powf(+0.0, -4.0) != HUGE_VALF");
589272343Sngie	}
590272343Sngie
591272343Sngie	z = powf(-0.0, -4.0);
592272343Sngie
593272343Sngie	if (z != HUGE_VALF) {
594272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
595272343Sngie		atf_tc_fail_nonfatal("powf(-0.0, -4.0) != HUGE_VALF");
596272343Sngie	}
597272343Sngie
598272343Sngie	z = powf(+0.0, -5.0);
599272343Sngie
600272343Sngie	if (z != HUGE_VALF) {
601272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
602272343Sngie		atf_tc_fail_nonfatal("powf(+0.0, -5.0) != HUGE_VALF");
603272343Sngie	}
604272343Sngie
605272343Sngie	z = powf(-0.0, -5.0);
606272343Sngie
607272343Sngie	if (z != -HUGE_VALF)
608272343Sngie		atf_tc_fail_nonfatal("powf(-0.0, -5.0) != -HUGE_VALF");
609272343Sngie}
610272343Sngie
611272343SngieATF_TC(powf_zero_y);
612272343SngieATF_TC_HEAD(powf_zero_y, tc)
613272343Sngie{
614272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0");
615272343Sngie}
616272343Sngie
617272343SngieATF_TC_BODY(powf_zero_y, tc)
618272343Sngie{
619272343Sngie	const float x[] =  { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
620272343Sngie	const float z = 0.0L / 0.0L;
621272343Sngie	size_t i;
622272343Sngie
623272343Sngie	/*
624272343Sngie	 * For any value of x (including NaN),
625272343Sngie	 * if y is +0.0 or -0.0, 1.0 is returned.
626272343Sngie	 */
627272343Sngie	if (powf(z, +0.0) != 1.0)
628272343Sngie		atf_tc_fail_nonfatal("powf(NaN, +0.0) != 1.0");
629272343Sngie
630272343Sngie	if (powf(z, -0.0) != 1.0)
631272343Sngie		atf_tc_fail_nonfatal("powf(NaN, -0.0) != 1.0");
632272343Sngie
633272343Sngie	for (i = 0; i < __arraycount(x); i++) {
634272343Sngie
635272343Sngie		if (powf(x[i], +0.0) != 1.0)
636272343Sngie			atf_tc_fail_nonfatal("powf(%0.01f, +0.0) != 1.0",x[i]);
637272343Sngie
638272343Sngie		if (powf(x[i], -0.0) != 1.0)
639272343Sngie			atf_tc_fail_nonfatal("powf(%0.01f, -0.0) != 1.0",x[i]);
640272343Sngie	}
641272343Sngie}
642272343Sngie
643272343SngieATF_TP_ADD_TCS(tp)
644272343Sngie{
645272343Sngie
646272343Sngie	ATF_TP_ADD_TC(tp, pow_nan_x);
647272343Sngie	ATF_TP_ADD_TC(tp, pow_nan_y);
648272343Sngie	ATF_TP_ADD_TC(tp, pow_inf_neg_x);
649272343Sngie	ATF_TP_ADD_TC(tp, pow_inf_neg_y);
650272343Sngie	ATF_TP_ADD_TC(tp, pow_inf_pos_x);
651272343Sngie	ATF_TP_ADD_TC(tp, pow_inf_pos_y);
652272343Sngie	ATF_TP_ADD_TC(tp, pow_one_neg_x);
653272343Sngie	ATF_TP_ADD_TC(tp, pow_one_pos_x);
654272343Sngie	ATF_TP_ADD_TC(tp, pow_zero_x);
655272343Sngie	ATF_TP_ADD_TC(tp, pow_zero_y);
656272343Sngie
657272343Sngie	ATF_TP_ADD_TC(tp, powf_nan_x);
658272343Sngie	ATF_TP_ADD_TC(tp, powf_nan_y);
659272343Sngie	ATF_TP_ADD_TC(tp, powf_inf_neg_x);
660272343Sngie	ATF_TP_ADD_TC(tp, powf_inf_neg_y);
661272343Sngie	ATF_TP_ADD_TC(tp, powf_inf_pos_x);
662272343Sngie	ATF_TP_ADD_TC(tp, powf_inf_pos_y);
663272343Sngie	ATF_TP_ADD_TC(tp, powf_one_neg_x);
664272343Sngie	ATF_TP_ADD_TC(tp, powf_one_pos_x);
665272343Sngie	ATF_TP_ADD_TC(tp, powf_zero_x);
666272343Sngie	ATF_TP_ADD_TC(tp, powf_zero_y);
667272343Sngie
668272343Sngie	return atf_no_error();
669272343Sngie}
670