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
37276478Sngie#ifdef __FreeBSD__
38276478Sngie#define isinff isinf
39276478Sngie#endif
40276478Sngie
41272343Sngie/*
42272343Sngie * pow(3)
43272343Sngie */
44272343SngieATF_TC(pow_nan_x);
45272343SngieATF_TC_HEAD(pow_nan_x, tc)
46272343Sngie{
47272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN");
48272343Sngie}
49272343Sngie
50272343SngieATF_TC_BODY(pow_nan_x, tc)
51272343Sngie{
52272343Sngie	const double x = 0.0L / 0.0L;
53272343Sngie
54272343Sngie	ATF_CHECK(isnan(pow(x, 2.0)) != 0);
55272343Sngie}
56272343Sngie
57272343SngieATF_TC(pow_nan_y);
58272343SngieATF_TC_HEAD(pow_nan_y, tc)
59272343Sngie{
60272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN");
61272343Sngie}
62272343Sngie
63272343SngieATF_TC_BODY(pow_nan_y, tc)
64272343Sngie{
65272343Sngie	const double y = 0.0L / 0.0L;
66272343Sngie
67272343Sngie	ATF_CHECK(isnan(pow(2.0, y)) != 0);
68272343Sngie}
69272343Sngie
70272343SngieATF_TC(pow_inf_neg_x);
71272343SngieATF_TC_HEAD(pow_inf_neg_x, tc)
72272343Sngie{
73272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0");
74272343Sngie}
75272343Sngie
76272343SngieATF_TC_BODY(pow_inf_neg_x, tc)
77272343Sngie{
78272343Sngie	const double x = -1.0L / 0.0L;
79272343Sngie	double z;
80272343Sngie
81272343Sngie	/*
82272343Sngie	 * If y is odd, y > 0, and x is -Inf, -Inf is returned.
83272343Sngie	 * If y is even, y > 0, and x is -Inf, +Inf is returned.
84272343Sngie	 */
85272343Sngie	z = pow(x, 3.0);
86272343Sngie
87272343Sngie	if (isinf(z) == 0 || signbit(z) == 0)
88272343Sngie		atf_tc_fail_nonfatal("pow(-Inf, 3.0) != -Inf");
89272343Sngie
90272343Sngie	z = pow(x, 4.0);
91272343Sngie
92272343Sngie	if (isinf(z) == 0 || signbit(z) != 0)
93272343Sngie		atf_tc_fail_nonfatal("pow(-Inf, 4.0) != +Inf");
94272343Sngie
95272343Sngie	/*
96272343Sngie	 * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
97272343Sngie	 * If y is even, y < 0, and x is -Inf, +0.0 is returned.
98272343Sngie	 */
99272343Sngie	z = pow(x, -3.0);
100272343Sngie
101272343Sngie	if (fabs(z) > 0.0 || signbit(z) == 0)
102272343Sngie		atf_tc_fail_nonfatal("pow(-Inf, -3.0) != -0.0");
103272343Sngie
104272343Sngie	z = pow(x, -4.0);
105272343Sngie
106272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
107272343Sngie		atf_tc_fail_nonfatal("pow(-Inf -4.0) != +0.0");
108272343Sngie}
109272343Sngie
110272343SngieATF_TC(pow_inf_neg_y);
111272343SngieATF_TC_HEAD(pow_inf_neg_y, tc)
112272343Sngie{
113272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0");
114272343Sngie}
115272343Sngie
116272343SngieATF_TC_BODY(pow_inf_neg_y, tc)
117272343Sngie{
118272343Sngie	const double y = -1.0L / 0.0L;
119272343Sngie	double z;
120272343Sngie
121272343Sngie	/*
122272343Sngie	 * If |x| < 1 and y is -Inf, +Inf is returned.
123272343Sngie	 * If |x| > 1 and y is -Inf, +0.0 is returned.
124272343Sngie	 */
125272343Sngie	z = pow(0.1, y);
126272343Sngie
127272343Sngie	if (isinf(z) == 0 || signbit(z) != 0)
128272343Sngie		atf_tc_fail_nonfatal("pow(0.1, -Inf) != +Inf");
129272343Sngie
130272343Sngie	z = pow(1.1, y);
131272343Sngie
132272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
133272343Sngie		atf_tc_fail_nonfatal("pow(1.1, -Inf) != +0.0");
134272343Sngie}
135272343Sngie
136272343SngieATF_TC(pow_inf_pos_x);
137272343SngieATF_TC_HEAD(pow_inf_pos_x, tc)
138272343Sngie{
139272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0");
140272343Sngie}
141272343Sngie
142272343SngieATF_TC_BODY(pow_inf_pos_x, tc)
143272343Sngie{
144272343Sngie	const double x = 1.0L / 0.0L;
145272343Sngie	double z;
146272343Sngie
147272343Sngie	/*
148272343Sngie	 * For y < 0, if x is +Inf, +0.0 is returned.
149272343Sngie	 * For y > 0, if x is +Inf, +Inf is returned.
150272343Sngie	 */
151272343Sngie	z = pow(x, -2.0);
152272343Sngie
153272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
154272343Sngie		atf_tc_fail_nonfatal("pow(+Inf, -2.0) != +0.0");
155272343Sngie
156272343Sngie	z = pow(x, 2.0);
157272343Sngie
158272343Sngie	if (isinf(z) == 0 || signbit(z) != 0)
159272343Sngie		atf_tc_fail_nonfatal("pow(+Inf, 2.0) != +Inf");
160272343Sngie}
161272343Sngie
162272343SngieATF_TC(pow_inf_pos_y);
163272343SngieATF_TC_HEAD(pow_inf_pos_y, tc)
164272343Sngie{
165272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0");
166272343Sngie}
167272343Sngie
168272343SngieATF_TC_BODY(pow_inf_pos_y, tc)
169272343Sngie{
170272343Sngie	const double y = 1.0L / 0.0L;
171272343Sngie	double z;
172272343Sngie
173272343Sngie	/*
174272343Sngie	 * If |x| < 1 and y is +Inf, +0.0 is returned.
175272343Sngie	 * If |x| > 1 and y is +Inf, +Inf is returned.
176272343Sngie	 */
177272343Sngie	z = pow(0.1, y);
178272343Sngie
179272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
180272343Sngie		atf_tc_fail_nonfatal("pow(0.1, +Inf) != +0.0");
181272343Sngie
182272343Sngie	z = pow(1.1, y);
183272343Sngie
184272343Sngie	if (isinf(z) == 0 || signbit(z) != 0)
185272343Sngie		atf_tc_fail_nonfatal("pow(1.1, +Inf) != +Inf");
186272343Sngie}
187272343Sngie
188272343SngieATF_TC(pow_one_neg_x);
189272343SngieATF_TC_HEAD(pow_one_neg_x, tc)
190272343Sngie{
191272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0");
192272343Sngie}
193272343Sngie
194272343SngieATF_TC_BODY(pow_one_neg_x, tc)
195272343Sngie{
196272343Sngie	const double infp = 1.0L / 0.0L;
197272343Sngie	const double infn = -1.0L / 0.0L;
198272343Sngie
199272343Sngie	/*
200272343Sngie	 * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
201272343Sngie	 */
202272343Sngie	ATF_REQUIRE(isinf(infp) != 0);
203272343Sngie	ATF_REQUIRE(isinf(infn) != 0);
204272343Sngie
205272343Sngie	if (pow(-1.0, infp) != 1.0) {
206272343Sngie		atf_tc_expect_fail("PR lib/45372");
207272343Sngie		atf_tc_fail_nonfatal("pow(-1.0, +Inf) != 1.0");
208272343Sngie	}
209272343Sngie
210272343Sngie	if (pow(-1.0, infn) != 1.0) {
211272343Sngie		atf_tc_expect_fail("PR lib/45372");
212272343Sngie		atf_tc_fail_nonfatal("pow(-1.0, -Inf) != 1.0");
213272343Sngie	}
214272343Sngie}
215272343Sngie
216272343SngieATF_TC(pow_one_pos_x);
217272343SngieATF_TC_HEAD(pow_one_pos_x, tc)
218272343Sngie{
219272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0");
220272343Sngie}
221272343Sngie
222272343SngieATF_TC_BODY(pow_one_pos_x, tc)
223272343Sngie{
224272343Sngie	const double y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
225272343Sngie	const double z = 0.0L / 0.0L;
226272343Sngie	size_t i;
227272343Sngie
228272343Sngie	/*
229272343Sngie	 * For any value of y (including NaN),
230272343Sngie	 * if x is 1.0, 1.0 shall be returned.
231272343Sngie	 */
232272343Sngie	if (pow(1.0, z) != 1.0)
233272343Sngie		atf_tc_fail_nonfatal("pow(1.0, NaN) != 1.0");
234272343Sngie
235272343Sngie	for (i = 0; i < __arraycount(y); i++) {
236272343Sngie
237272343Sngie		if (pow(1.0, y[i]) != 1.0)
238272343Sngie			atf_tc_fail_nonfatal("pow(1.0, %0.01f) != 1.0", y[i]);
239272343Sngie	}
240272343Sngie}
241272343Sngie
242272343SngieATF_TC(pow_zero_x);
243272343SngieATF_TC_HEAD(pow_zero_x, tc)
244272343Sngie{
245272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE");
246272343Sngie}
247272343Sngie
248272343SngieATF_TC_BODY(pow_zero_x, tc)
249272343Sngie{
250272343Sngie	double z;
251272343Sngie
252272343Sngie	/*
253272343Sngie	 * If x is +0.0 or -0.0, y > 0, and y
254272343Sngie	 * is an odd integer, x is returned.
255272343Sngie	 */
256272343Sngie	z = pow(+0.0, 3.0);
257272343Sngie
258272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
259272343Sngie		atf_tc_fail_nonfatal("pow(+0.0, 3.0) != +0.0");
260272343Sngie
261272343Sngie	z = pow(-0.0, 3.0);
262272343Sngie
263272343Sngie	if (fabs(z) > 0.0 || signbit(z) == 0)
264272343Sngie		atf_tc_fail_nonfatal("pow(-0.0, 3.0) != -0.0");
265272343Sngie
266272343Sngie	/*
267272343Sngie	 * If y > 0 and not an odd integer,
268272343Sngie	 * if x is +0.0 or -0.0, +0.0 is returned.
269272343Sngie	 */
270272343Sngie	z = pow(+0.0, 4.0);
271272343Sngie
272272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
273272343Sngie		atf_tc_fail_nonfatal("pow(+0.0, 4.0) != +0.0");
274272343Sngie
275272343Sngie	z = pow(-0.0, 4.0);
276272343Sngie
277272343Sngie	if (fabs(z) > 0.0 || signbit(z) != 0)
278272343Sngie		atf_tc_fail_nonfatal("pow(-0.0, 4.0) != +0.0");
279272343Sngie
280272343Sngie	/*
281272343Sngie	 * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
282272343Sngie	 * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
283272343Sngie	 */
284272343Sngie	z = pow(+0.0, -4.0);
285272343Sngie
286272343Sngie	if (z != HUGE_VAL) {
287272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
288272343Sngie		atf_tc_fail_nonfatal("pow(+0.0, -4.0) != HUGE_VAL");
289272343Sngie	}
290272343Sngie
291272343Sngie	z = pow(-0.0, -4.0);
292272343Sngie
293272343Sngie	if (z != HUGE_VAL) {
294272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
295272343Sngie		atf_tc_fail_nonfatal("pow(-0.0, -4.0) != HUGE_VAL");
296272343Sngie	}
297272343Sngie
298272343Sngie	z = pow(+0.0, -5.0);
299272343Sngie
300272343Sngie	if (z != HUGE_VAL) {
301272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
302272343Sngie		atf_tc_fail_nonfatal("pow(+0.0, -5.0) != HUGE_VAL");
303272343Sngie	}
304272343Sngie
305272343Sngie	z = pow(-0.0, -5.0);
306272343Sngie
307272343Sngie	if (z != -HUGE_VAL)
308272343Sngie		atf_tc_fail_nonfatal("pow(-0.0, -5.0) != -HUGE_VAL");
309272343Sngie}
310272343Sngie
311272343SngieATF_TC(pow_zero_y);
312272343SngieATF_TC_HEAD(pow_zero_y, tc)
313272343Sngie{
314272343Sngie	atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0");
315272343Sngie}
316272343Sngie
317272343SngieATF_TC_BODY(pow_zero_y, tc)
318272343Sngie{
319272343Sngie	const double x[] =  { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
320272343Sngie	const double z = 0.0L / 0.0L;
321272343Sngie	size_t i;
322272343Sngie
323272343Sngie	/*
324272343Sngie	 * For any value of x (including NaN),
325272343Sngie	 * if y is +0.0 or -0.0, 1.0 is returned.
326272343Sngie	 */
327272343Sngie	if (pow(z, +0.0) != 1.0)
328272343Sngie		atf_tc_fail_nonfatal("pow(NaN, +0.0) != 1.0");
329272343Sngie
330272343Sngie	if (pow(z, -0.0) != 1.0)
331272343Sngie		atf_tc_fail_nonfatal("pow(NaN, -0.0) != 1.0");
332272343Sngie
333272343Sngie	for (i = 0; i < __arraycount(x); i++) {
334272343Sngie
335272343Sngie		if (pow(x[i], +0.0) != 1.0)
336272343Sngie			atf_tc_fail_nonfatal("pow(%0.01f, +0.0) != 1.0", x[i]);
337272343Sngie
338272343Sngie		if (pow(x[i], -0.0) != 1.0)
339272343Sngie			atf_tc_fail_nonfatal("pow(%0.01f, -0.0) != 1.0", x[i]);
340272343Sngie	}
341272343Sngie}
342272343Sngie
343272343Sngie/*
344272343Sngie * powf(3)
345272343Sngie */
346272343SngieATF_TC(powf_nan_x);
347272343SngieATF_TC_HEAD(powf_nan_x, tc)
348272343Sngie{
349272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN");
350272343Sngie}
351272343Sngie
352272343SngieATF_TC_BODY(powf_nan_x, tc)
353272343Sngie{
354272343Sngie	const float x = 0.0L / 0.0L;
355272343Sngie
356272343Sngie	ATF_CHECK(isnanf(powf(x, 2.0)) != 0);
357272343Sngie}
358272343Sngie
359272343SngieATF_TC(powf_nan_y);
360272343SngieATF_TC_HEAD(powf_nan_y, tc)
361272343Sngie{
362272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN");
363272343Sngie}
364272343Sngie
365272343SngieATF_TC_BODY(powf_nan_y, tc)
366272343Sngie{
367272343Sngie	const float y = 0.0L / 0.0L;
368272343Sngie
369272343Sngie	ATF_CHECK(isnanf(powf(2.0, y)) != 0);
370272343Sngie}
371272343Sngie
372272343SngieATF_TC(powf_inf_neg_x);
373272343SngieATF_TC_HEAD(powf_inf_neg_x, tc)
374272343Sngie{
375272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0");
376272343Sngie}
377272343Sngie
378272343SngieATF_TC_BODY(powf_inf_neg_x, tc)
379272343Sngie{
380272343Sngie	const float x = -1.0L / 0.0L;
381272343Sngie	float z;
382272343Sngie
383272343Sngie	/*
384272343Sngie	 * If y is odd, y > 0, and x is -Inf, -Inf is returned.
385272343Sngie	 * If y is even, y > 0, and x is -Inf, +Inf is returned.
386272343Sngie	 */
387272343Sngie	z = powf(x, 3.0);
388272343Sngie
389272343Sngie	if (isinff(z) == 0 || signbit(z) == 0)
390272343Sngie		atf_tc_fail_nonfatal("powf(-Inf, 3.0) != -Inf");
391272343Sngie
392272343Sngie	z = powf(x, 4.0);
393272343Sngie
394272343Sngie	if (isinff(z) == 0 || signbit(z) != 0)
395272343Sngie		atf_tc_fail_nonfatal("powf(-Inf, 4.0) != +Inf");
396272343Sngie
397272343Sngie	/*
398272343Sngie	 * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
399272343Sngie	 * If y is even, y < 0, and x is -Inf, +0.0 is returned.
400272343Sngie	 */
401272343Sngie	z = powf(x, -3.0);
402272343Sngie
403272343Sngie	if (fabsf(z) > 0.0 || signbit(z) == 0) {
404272343Sngie		atf_tc_expect_fail("PR lib/45372");
405272343Sngie		atf_tc_fail_nonfatal("powf(-Inf, -3.0) != -0.0");
406272343Sngie	}
407272343Sngie
408272343Sngie	z = powf(x, -4.0);
409272343Sngie
410272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
411272343Sngie		atf_tc_fail_nonfatal("powf(-Inf -4.0) != +0.0");
412272343Sngie}
413272343Sngie
414272343SngieATF_TC(powf_inf_neg_y);
415272343SngieATF_TC_HEAD(powf_inf_neg_y, tc)
416272343Sngie{
417272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0");
418272343Sngie}
419272343Sngie
420272343SngieATF_TC_BODY(powf_inf_neg_y, tc)
421272343Sngie{
422272343Sngie	const float y = -1.0L / 0.0L;
423272343Sngie	float z;
424272343Sngie
425272343Sngie	/*
426272343Sngie	 * If |x| < 1 and y is -Inf, +Inf is returned.
427272343Sngie	 * If |x| > 1 and y is -Inf, +0.0 is returned.
428272343Sngie	 */
429272343Sngie	z = powf(0.1, y);
430272343Sngie
431272343Sngie	if (isinff(z) == 0 || signbit(z) != 0)
432272343Sngie		atf_tc_fail_nonfatal("powf(0.1, -Inf) != +Inf");
433272343Sngie
434272343Sngie	z = powf(1.1, y);
435272343Sngie
436272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
437272343Sngie		atf_tc_fail_nonfatal("powf(1.1, -Inf) != +0.0");
438272343Sngie}
439272343Sngie
440272343SngieATF_TC(powf_inf_pos_x);
441272343SngieATF_TC_HEAD(powf_inf_pos_x, tc)
442272343Sngie{
443272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0");
444272343Sngie}
445272343Sngie
446272343SngieATF_TC_BODY(powf_inf_pos_x, tc)
447272343Sngie{
448272343Sngie	const float x = 1.0L / 0.0L;
449272343Sngie	float z;
450272343Sngie
451272343Sngie	/*
452272343Sngie	 * For y < 0, if x is +Inf, +0.0 is returned.
453272343Sngie	 * For y > 0, if x is +Inf, +Inf is returned.
454272343Sngie	 */
455272343Sngie	z = powf(x, -2.0);
456272343Sngie
457272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
458272343Sngie		atf_tc_fail_nonfatal("powf(+Inf, -2.0) != +0.0");
459272343Sngie
460272343Sngie	z = powf(x, 2.0);
461272343Sngie
462272343Sngie	if (isinff(z) == 0 || signbit(z) != 0)
463272343Sngie		atf_tc_fail_nonfatal("powf(+Inf, 2.0) != +Inf");
464272343Sngie}
465272343Sngie
466272343SngieATF_TC(powf_inf_pos_y);
467272343SngieATF_TC_HEAD(powf_inf_pos_y, tc)
468272343Sngie{
469272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0");
470272343Sngie}
471272343Sngie
472272343SngieATF_TC_BODY(powf_inf_pos_y, tc)
473272343Sngie{
474272343Sngie	const float y = 1.0L / 0.0L;
475272343Sngie	float z;
476272343Sngie
477272343Sngie	/*
478272343Sngie	 * If |x| < 1 and y is +Inf, +0.0 is returned.
479272343Sngie	 * If |x| > 1 and y is +Inf, +Inf is returned.
480272343Sngie	 */
481272343Sngie	z = powf(0.1, y);
482272343Sngie
483272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
484272343Sngie		atf_tc_fail_nonfatal("powf(0.1, +Inf) != +0.0");
485272343Sngie
486272343Sngie	z = powf(1.1, y);
487272343Sngie
488272343Sngie	if (isinff(z) == 0 || signbit(z) != 0)
489272343Sngie		atf_tc_fail_nonfatal("powf(1.1, +Inf) != +Inf");
490272343Sngie}
491272343Sngie
492272343SngieATF_TC(powf_one_neg_x);
493272343SngieATF_TC_HEAD(powf_one_neg_x, tc)
494272343Sngie{
495272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0");
496272343Sngie}
497272343Sngie
498272343SngieATF_TC_BODY(powf_one_neg_x, tc)
499272343Sngie{
500272343Sngie	const float infp = 1.0L / 0.0L;
501272343Sngie	const float infn = -1.0L / 0.0L;
502272343Sngie
503272343Sngie	/*
504272343Sngie	 * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
505272343Sngie	 */
506272343Sngie	ATF_REQUIRE(isinff(infp) != 0);
507272343Sngie	ATF_REQUIRE(isinff(infn) != 0);
508272343Sngie
509272343Sngie	if (powf(-1.0, infp) != 1.0) {
510272343Sngie		atf_tc_expect_fail("PR lib/45372");
511272343Sngie		atf_tc_fail_nonfatal("powf(-1.0, +Inf) != 1.0");
512272343Sngie	}
513272343Sngie
514272343Sngie	if (powf(-1.0, infn) != 1.0) {
515272343Sngie		atf_tc_expect_fail("PR lib/45372");
516272343Sngie		atf_tc_fail_nonfatal("powf(-1.0, -Inf) != 1.0");
517272343Sngie	}
518272343Sngie}
519272343Sngie
520272343SngieATF_TC(powf_one_pos_x);
521272343SngieATF_TC_HEAD(powf_one_pos_x, tc)
522272343Sngie{
523272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0");
524272343Sngie}
525272343Sngie
526272343SngieATF_TC_BODY(powf_one_pos_x, tc)
527272343Sngie{
528272343Sngie	const float y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
529272343Sngie	const float z = 0.0L / 0.0L;
530272343Sngie	size_t i;
531272343Sngie
532272343Sngie	/*
533272343Sngie	 * For any value of y (including NaN),
534272343Sngie	 * if x is 1.0, 1.0 shall be returned.
535272343Sngie	 */
536272343Sngie	if (powf(1.0, z) != 1.0)
537272343Sngie		atf_tc_fail_nonfatal("powf(1.0, NaN) != 1.0");
538272343Sngie
539272343Sngie	for (i = 0; i < __arraycount(y); i++) {
540272343Sngie
541272343Sngie		if (powf(1.0, y[i]) != 1.0)
542272343Sngie			atf_tc_fail_nonfatal("powf(1.0, %0.01f) != 1.0", y[i]);
543272343Sngie	}
544272343Sngie}
545272343Sngie
546272343SngieATF_TC(powf_zero_x);
547272343SngieATF_TC_HEAD(powf_zero_x, tc)
548272343Sngie{
549272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE");
550272343Sngie}
551272343Sngie
552272343SngieATF_TC_BODY(powf_zero_x, tc)
553272343Sngie{
554272343Sngie	float z;
555272343Sngie
556272343Sngie	/*
557272343Sngie	 * If x is +0.0 or -0.0, y > 0, and y
558272343Sngie	 * is an odd integer, x is returned.
559272343Sngie	 */
560272343Sngie	z = powf(+0.0, 3.0);
561272343Sngie
562272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
563272343Sngie		atf_tc_fail_nonfatal("powf(+0.0, 3.0) != +0.0");
564272343Sngie
565272343Sngie	z = powf(-0.0, 3.0);
566272343Sngie
567272343Sngie	if (fabsf(z) > 0.0 || signbit(z) == 0)
568272343Sngie		atf_tc_fail_nonfatal("powf(-0.0, 3.0) != -0.0");
569272343Sngie
570272343Sngie	/*
571272343Sngie	 * If y > 0 and not an odd integer,
572272343Sngie	 * if x is +0.0 or -0.0, +0.0 is returned.
573272343Sngie	 */
574272343Sngie	z = powf(+0.0, 4.0);
575272343Sngie
576272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
577272343Sngie		atf_tc_fail_nonfatal("powf(+0.0, 4.0) != +0.0");
578272343Sngie
579272343Sngie	z = powf(-0.0, 4.0);
580272343Sngie
581272343Sngie	if (fabsf(z) > 0.0 || signbit(z) != 0)
582272343Sngie		atf_tc_fail_nonfatal("powf(-0.0, 4.0) != +0.0");
583272343Sngie
584272343Sngie	/*
585272343Sngie	 * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
586272343Sngie	 * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
587272343Sngie	 */
588272343Sngie	z = powf(+0.0, -4.0);
589272343Sngie
590272343Sngie	if (z != HUGE_VALF) {
591272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
592272343Sngie		atf_tc_fail_nonfatal("powf(+0.0, -4.0) != HUGE_VALF");
593272343Sngie	}
594272343Sngie
595272343Sngie	z = powf(-0.0, -4.0);
596272343Sngie
597272343Sngie	if (z != HUGE_VALF) {
598272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
599272343Sngie		atf_tc_fail_nonfatal("powf(-0.0, -4.0) != HUGE_VALF");
600272343Sngie	}
601272343Sngie
602272343Sngie	z = powf(+0.0, -5.0);
603272343Sngie
604272343Sngie	if (z != HUGE_VALF) {
605272343Sngie		atf_tc_expect_fail("PR port-amd64/45391");
606272343Sngie		atf_tc_fail_nonfatal("powf(+0.0, -5.0) != HUGE_VALF");
607272343Sngie	}
608272343Sngie
609272343Sngie	z = powf(-0.0, -5.0);
610272343Sngie
611272343Sngie	if (z != -HUGE_VALF)
612272343Sngie		atf_tc_fail_nonfatal("powf(-0.0, -5.0) != -HUGE_VALF");
613272343Sngie}
614272343Sngie
615272343SngieATF_TC(powf_zero_y);
616272343SngieATF_TC_HEAD(powf_zero_y, tc)
617272343Sngie{
618272343Sngie	atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0");
619272343Sngie}
620272343Sngie
621272343SngieATF_TC_BODY(powf_zero_y, tc)
622272343Sngie{
623272343Sngie	const float x[] =  { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
624272343Sngie	const float z = 0.0L / 0.0L;
625272343Sngie	size_t i;
626272343Sngie
627272343Sngie	/*
628272343Sngie	 * For any value of x (including NaN),
629272343Sngie	 * if y is +0.0 or -0.0, 1.0 is returned.
630272343Sngie	 */
631272343Sngie	if (powf(z, +0.0) != 1.0)
632272343Sngie		atf_tc_fail_nonfatal("powf(NaN, +0.0) != 1.0");
633272343Sngie
634272343Sngie	if (powf(z, -0.0) != 1.0)
635272343Sngie		atf_tc_fail_nonfatal("powf(NaN, -0.0) != 1.0");
636272343Sngie
637272343Sngie	for (i = 0; i < __arraycount(x); i++) {
638272343Sngie
639272343Sngie		if (powf(x[i], +0.0) != 1.0)
640272343Sngie			atf_tc_fail_nonfatal("powf(%0.01f, +0.0) != 1.0",x[i]);
641272343Sngie
642272343Sngie		if (powf(x[i], -0.0) != 1.0)
643272343Sngie			atf_tc_fail_nonfatal("powf(%0.01f, -0.0) != 1.0",x[i]);
644272343Sngie	}
645272343Sngie}
646272343Sngie
647272343SngieATF_TP_ADD_TCS(tp)
648272343Sngie{
649272343Sngie
650272343Sngie	ATF_TP_ADD_TC(tp, pow_nan_x);
651272343Sngie	ATF_TP_ADD_TC(tp, pow_nan_y);
652272343Sngie	ATF_TP_ADD_TC(tp, pow_inf_neg_x);
653272343Sngie	ATF_TP_ADD_TC(tp, pow_inf_neg_y);
654272343Sngie	ATF_TP_ADD_TC(tp, pow_inf_pos_x);
655272343Sngie	ATF_TP_ADD_TC(tp, pow_inf_pos_y);
656272343Sngie	ATF_TP_ADD_TC(tp, pow_one_neg_x);
657272343Sngie	ATF_TP_ADD_TC(tp, pow_one_pos_x);
658272343Sngie	ATF_TP_ADD_TC(tp, pow_zero_x);
659272343Sngie	ATF_TP_ADD_TC(tp, pow_zero_y);
660272343Sngie
661272343Sngie	ATF_TP_ADD_TC(tp, powf_nan_x);
662272343Sngie	ATF_TP_ADD_TC(tp, powf_nan_y);
663272343Sngie	ATF_TP_ADD_TC(tp, powf_inf_neg_x);
664272343Sngie	ATF_TP_ADD_TC(tp, powf_inf_neg_y);
665272343Sngie	ATF_TP_ADD_TC(tp, powf_inf_pos_x);
666272343Sngie	ATF_TP_ADD_TC(tp, powf_inf_pos_y);
667272343Sngie	ATF_TP_ADD_TC(tp, powf_one_neg_x);
668272343Sngie	ATF_TP_ADD_TC(tp, powf_one_pos_x);
669272343Sngie	ATF_TP_ADD_TC(tp, powf_zero_x);
670272343Sngie	ATF_TP_ADD_TC(tp, powf_zero_y);
671272343Sngie
672272343Sngie	return atf_no_error();
673272343Sngie}
674