xref: /freebsd/contrib/netbsd-tests/lib/libm/t_pow.c (revision 924226fba12cc9a228c73b956e1b7fa24c60b055)
1 /* $NetBSD: t_pow.c,v 1.5 2017/01/20 21:15:56 maya Exp $ */
2 
3 /*-
4  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jukka Ruohonen.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: t_pow.c,v 1.5 2017/01/20 21:15:56 maya Exp $");
33 
34 #include <atf-c.h>
35 #include <math.h>
36 
37 /*
38  * pow(3)
39  */
40 ATF_TC(pow_nan_x);
41 ATF_TC_HEAD(pow_nan_x, tc)
42 {
43 	atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN");
44 }
45 
46 ATF_TC_BODY(pow_nan_x, tc)
47 {
48 	const double x = 0.0L / 0.0L;
49 
50 	ATF_CHECK(isnan(pow(x, 2.0)) != 0);
51 }
52 
53 ATF_TC(pow_nan_y);
54 ATF_TC_HEAD(pow_nan_y, tc)
55 {
56 	atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN");
57 }
58 
59 ATF_TC_BODY(pow_nan_y, tc)
60 {
61 	const double y = 0.0L / 0.0L;
62 
63 	ATF_CHECK(isnan(pow(2.0, y)) != 0);
64 }
65 
66 ATF_TC(pow_inf_neg_x);
67 ATF_TC_HEAD(pow_inf_neg_x, tc)
68 {
69 	atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0");
70 }
71 
72 ATF_TC_BODY(pow_inf_neg_x, tc)
73 {
74 	const double x = -1.0L / 0.0L;
75 	double z;
76 
77 	/*
78 	 * If y is odd, y > 0, and x is -Inf, -Inf is returned.
79 	 * If y is even, y > 0, and x is -Inf, +Inf is returned.
80 	 */
81 	z = pow(x, 3.0);
82 
83 	if (isinf(z) == 0 || signbit(z) == 0)
84 		atf_tc_fail_nonfatal("pow(-Inf, 3.0) != -Inf");
85 
86 	z = pow(x, 4.0);
87 
88 	if (isinf(z) == 0 || signbit(z) != 0)
89 		atf_tc_fail_nonfatal("pow(-Inf, 4.0) != +Inf");
90 
91 	/*
92 	 * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
93 	 * If y is even, y < 0, and x is -Inf, +0.0 is returned.
94 	 */
95 	z = pow(x, -3.0);
96 
97 	if (fabs(z) > 0.0 || signbit(z) == 0)
98 		atf_tc_fail_nonfatal("pow(-Inf, -3.0) != -0.0");
99 
100 	z = pow(x, -4.0);
101 
102 	if (fabs(z) > 0.0 || signbit(z) != 0)
103 		atf_tc_fail_nonfatal("pow(-Inf -4.0) != +0.0");
104 }
105 
106 ATF_TC(pow_inf_neg_y);
107 ATF_TC_HEAD(pow_inf_neg_y, tc)
108 {
109 	atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0");
110 }
111 
112 ATF_TC_BODY(pow_inf_neg_y, tc)
113 {
114 	const double y = -1.0L / 0.0L;
115 	double z;
116 
117 	/*
118 	 * If |x| < 1 and y is -Inf, +Inf is returned.
119 	 * If |x| > 1 and y is -Inf, +0.0 is returned.
120 	 */
121 	z = pow(0.1, y);
122 
123 	if (isinf(z) == 0 || signbit(z) != 0)
124 		atf_tc_fail_nonfatal("pow(0.1, -Inf) != +Inf");
125 
126 	z = pow(1.1, y);
127 
128 	if (fabs(z) > 0.0 || signbit(z) != 0)
129 		atf_tc_fail_nonfatal("pow(1.1, -Inf) != +0.0");
130 }
131 
132 ATF_TC(pow_inf_pos_x);
133 ATF_TC_HEAD(pow_inf_pos_x, tc)
134 {
135 	atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0");
136 }
137 
138 ATF_TC_BODY(pow_inf_pos_x, tc)
139 {
140 	const double x = 1.0L / 0.0L;
141 	double z;
142 
143 	/*
144 	 * For y < 0, if x is +Inf, +0.0 is returned.
145 	 * For y > 0, if x is +Inf, +Inf is returned.
146 	 */
147 	z = pow(x, -2.0);
148 
149 	if (fabs(z) > 0.0 || signbit(z) != 0)
150 		atf_tc_fail_nonfatal("pow(+Inf, -2.0) != +0.0");
151 
152 	z = pow(x, 2.0);
153 
154 	if (isinf(z) == 0 || signbit(z) != 0)
155 		atf_tc_fail_nonfatal("pow(+Inf, 2.0) != +Inf");
156 }
157 
158 ATF_TC(pow_inf_pos_y);
159 ATF_TC_HEAD(pow_inf_pos_y, tc)
160 {
161 	atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0");
162 }
163 
164 ATF_TC_BODY(pow_inf_pos_y, tc)
165 {
166 	const double y = 1.0L / 0.0L;
167 	double z;
168 
169 	/*
170 	 * If |x| < 1 and y is +Inf, +0.0 is returned.
171 	 * If |x| > 1 and y is +Inf, +Inf is returned.
172 	 */
173 	z = pow(0.1, y);
174 
175 	if (fabs(z) > 0.0 || signbit(z) != 0)
176 		atf_tc_fail_nonfatal("pow(0.1, +Inf) != +0.0");
177 
178 	z = pow(1.1, y);
179 
180 	if (isinf(z) == 0 || signbit(z) != 0)
181 		atf_tc_fail_nonfatal("pow(1.1, +Inf) != +Inf");
182 }
183 
184 ATF_TC(pow_one_neg_x);
185 ATF_TC_HEAD(pow_one_neg_x, tc)
186 {
187 	atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0");
188 }
189 
190 ATF_TC_BODY(pow_one_neg_x, tc)
191 {
192 	const double infp = 1.0L / 0.0L;
193 	const double infn = -1.0L / 0.0L;
194 
195 	/*
196 	 * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
197 	 */
198 	ATF_REQUIRE(isinf(infp) != 0);
199 	ATF_REQUIRE(isinf(infn) != 0);
200 
201 	if (pow(-1.0, infp) != 1.0) {
202 		atf_tc_expect_fail("PR lib/45372");
203 		atf_tc_fail_nonfatal("pow(-1.0, +Inf) != 1.0");
204 	}
205 
206 	if (pow(-1.0, infn) != 1.0) {
207 		atf_tc_expect_fail("PR lib/45372");
208 		atf_tc_fail_nonfatal("pow(-1.0, -Inf) != 1.0");
209 	}
210 }
211 
212 ATF_TC(pow_one_pos_x);
213 ATF_TC_HEAD(pow_one_pos_x, tc)
214 {
215 	atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0");
216 }
217 
218 ATF_TC_BODY(pow_one_pos_x, tc)
219 {
220 	const double y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
221 	const double z = 0.0L / 0.0L;
222 	size_t i;
223 
224 	/*
225 	 * For any value of y (including NaN),
226 	 * if x is 1.0, 1.0 shall be returned.
227 	 */
228 	if (pow(1.0, z) != 1.0)
229 		atf_tc_fail_nonfatal("pow(1.0, NaN) != 1.0");
230 
231 	for (i = 0; i < __arraycount(y); i++) {
232 
233 		if (pow(1.0, y[i]) != 1.0)
234 			atf_tc_fail_nonfatal("pow(1.0, %0.01f) != 1.0", y[i]);
235 	}
236 }
237 
238 ATF_TC(pow_zero_x);
239 ATF_TC_HEAD(pow_zero_x, tc)
240 {
241 	atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE");
242 }
243 
244 ATF_TC_BODY(pow_zero_x, tc)
245 {
246 	double z;
247 
248 	/*
249 	 * If x is +0.0 or -0.0, y > 0, and y
250 	 * is an odd integer, x is returned.
251 	 */
252 	z = pow(+0.0, 3.0);
253 
254 	if (fabs(z) > 0.0 || signbit(z) != 0)
255 		atf_tc_fail_nonfatal("pow(+0.0, 3.0) != +0.0");
256 
257 	z = pow(-0.0, 3.0);
258 
259 	if (fabs(z) > 0.0 || signbit(z) == 0)
260 		atf_tc_fail_nonfatal("pow(-0.0, 3.0) != -0.0");
261 
262 	/*
263 	 * If y > 0 and not an odd integer,
264 	 * if x is +0.0 or -0.0, +0.0 is returned.
265 	 */
266 	z = pow(+0.0, 4.0);
267 
268 	if (fabs(z) > 0.0 || signbit(z) != 0)
269 		atf_tc_fail_nonfatal("pow(+0.0, 4.0) != +0.0");
270 
271 	z = pow(-0.0, 4.0);
272 
273 	if (fabs(z) > 0.0 || signbit(z) != 0)
274 		atf_tc_fail_nonfatal("pow(-0.0, 4.0) != +0.0");
275 
276 	/*
277 	 * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
278 	 * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
279 	 */
280 	z = pow(+0.0, -4.0);
281 
282 	if (z != HUGE_VAL) {
283 		atf_tc_fail_nonfatal("pow(+0.0, -4.0) != HUGE_VAL");
284 	}
285 
286 	z = pow(-0.0, -4.0);
287 
288 	if (z != HUGE_VAL) {
289 		atf_tc_fail_nonfatal("pow(-0.0, -4.0) != HUGE_VAL");
290 	}
291 
292 	z = pow(+0.0, -5.0);
293 
294 	if (z != HUGE_VAL) {
295 		atf_tc_fail_nonfatal("pow(+0.0, -5.0) != HUGE_VAL");
296 	}
297 
298 	z = pow(-0.0, -5.0);
299 
300 	if (z != -HUGE_VAL)
301 		atf_tc_fail_nonfatal("pow(-0.0, -5.0) != -HUGE_VAL");
302 }
303 
304 ATF_TC(pow_zero_y);
305 ATF_TC_HEAD(pow_zero_y, tc)
306 {
307 	atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0");
308 }
309 
310 ATF_TC_BODY(pow_zero_y, tc)
311 {
312 	const double x[] =  { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
313 	const double z = 0.0L / 0.0L;
314 	size_t i;
315 
316 	/*
317 	 * For any value of x (including NaN),
318 	 * if y is +0.0 or -0.0, 1.0 is returned.
319 	 */
320 	if (pow(z, +0.0) != 1.0)
321 		atf_tc_fail_nonfatal("pow(NaN, +0.0) != 1.0");
322 
323 	if (pow(z, -0.0) != 1.0)
324 		atf_tc_fail_nonfatal("pow(NaN, -0.0) != 1.0");
325 
326 	for (i = 0; i < __arraycount(x); i++) {
327 
328 		if (pow(x[i], +0.0) != 1.0)
329 			atf_tc_fail_nonfatal("pow(%0.01f, +0.0) != 1.0", x[i]);
330 
331 		if (pow(x[i], -0.0) != 1.0)
332 			atf_tc_fail_nonfatal("pow(%0.01f, -0.0) != 1.0", x[i]);
333 	}
334 }
335 
336 /*
337  * powf(3)
338  */
339 ATF_TC(powf_nan_x);
340 ATF_TC_HEAD(powf_nan_x, tc)
341 {
342 	atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN");
343 }
344 
345 ATF_TC_BODY(powf_nan_x, tc)
346 {
347 	const float x = 0.0L / 0.0L;
348 
349 	ATF_CHECK(isnanf(powf(x, 2.0)) != 0);
350 }
351 
352 ATF_TC(powf_nan_y);
353 ATF_TC_HEAD(powf_nan_y, tc)
354 {
355 	atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN");
356 }
357 
358 ATF_TC_BODY(powf_nan_y, tc)
359 {
360 	const float y = 0.0L / 0.0L;
361 
362 	ATF_CHECK(isnanf(powf(2.0, y)) != 0);
363 }
364 
365 ATF_TC(powf_inf_neg_x);
366 ATF_TC_HEAD(powf_inf_neg_x, tc)
367 {
368 	atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0");
369 }
370 
371 ATF_TC_BODY(powf_inf_neg_x, tc)
372 {
373 	const float x = -1.0L / 0.0L;
374 	float z;
375 
376 	/*
377 	 * If y is odd, y > 0, and x is -Inf, -Inf is returned.
378 	 * If y is even, y > 0, and x is -Inf, +Inf is returned.
379 	 */
380 	z = powf(x, 3.0);
381 
382 	if (isinf(z) == 0 || signbit(z) == 0)
383 		atf_tc_fail_nonfatal("powf(-Inf, 3.0) != -Inf");
384 
385 	z = powf(x, 4.0);
386 
387 	if (isinf(z) == 0 || signbit(z) != 0)
388 		atf_tc_fail_nonfatal("powf(-Inf, 4.0) != +Inf");
389 
390 	/*
391 	 * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
392 	 * If y is even, y < 0, and x is -Inf, +0.0 is returned.
393 	 */
394 	z = powf(x, -3.0);
395 
396 	if (fabsf(z) > 0.0 || signbit(z) == 0) {
397 		atf_tc_expect_fail("PR lib/45372");
398 		atf_tc_fail_nonfatal("powf(-Inf, -3.0) != -0.0");
399 	}
400 
401 	z = powf(x, -4.0);
402 
403 	if (fabsf(z) > 0.0 || signbit(z) != 0)
404 		atf_tc_fail_nonfatal("powf(-Inf -4.0) != +0.0");
405 }
406 
407 ATF_TC(powf_inf_neg_y);
408 ATF_TC_HEAD(powf_inf_neg_y, tc)
409 {
410 	atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0");
411 }
412 
413 ATF_TC_BODY(powf_inf_neg_y, tc)
414 {
415 	const float y = -1.0L / 0.0L;
416 	float z;
417 
418 	/*
419 	 * If |x| < 1 and y is -Inf, +Inf is returned.
420 	 * If |x| > 1 and y is -Inf, +0.0 is returned.
421 	 */
422 	z = powf(0.1, y);
423 
424 	if (isinf(z) == 0 || signbit(z) != 0)
425 		atf_tc_fail_nonfatal("powf(0.1, -Inf) != +Inf");
426 
427 	z = powf(1.1, y);
428 
429 	if (fabsf(z) > 0.0 || signbit(z) != 0)
430 		atf_tc_fail_nonfatal("powf(1.1, -Inf) != +0.0");
431 }
432 
433 ATF_TC(powf_inf_pos_x);
434 ATF_TC_HEAD(powf_inf_pos_x, tc)
435 {
436 	atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0");
437 }
438 
439 ATF_TC_BODY(powf_inf_pos_x, tc)
440 {
441 	const float x = 1.0L / 0.0L;
442 	float z;
443 
444 	/*
445 	 * For y < 0, if x is +Inf, +0.0 is returned.
446 	 * For y > 0, if x is +Inf, +Inf is returned.
447 	 */
448 	z = powf(x, -2.0);
449 
450 	if (fabsf(z) > 0.0 || signbit(z) != 0)
451 		atf_tc_fail_nonfatal("powf(+Inf, -2.0) != +0.0");
452 
453 	z = powf(x, 2.0);
454 
455 	if (isinf(z) == 0 || signbit(z) != 0)
456 		atf_tc_fail_nonfatal("powf(+Inf, 2.0) != +Inf");
457 }
458 
459 ATF_TC(powf_inf_pos_y);
460 ATF_TC_HEAD(powf_inf_pos_y, tc)
461 {
462 	atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0");
463 }
464 
465 ATF_TC_BODY(powf_inf_pos_y, tc)
466 {
467 	const float y = 1.0L / 0.0L;
468 	float z;
469 
470 	/*
471 	 * If |x| < 1 and y is +Inf, +0.0 is returned.
472 	 * If |x| > 1 and y is +Inf, +Inf is returned.
473 	 */
474 	z = powf(0.1, y);
475 
476 	if (fabsf(z) > 0.0 || signbit(z) != 0)
477 		atf_tc_fail_nonfatal("powf(0.1, +Inf) != +0.0");
478 
479 	z = powf(1.1, y);
480 
481 	if (isinf(z) == 0 || signbit(z) != 0)
482 		atf_tc_fail_nonfatal("powf(1.1, +Inf) != +Inf");
483 }
484 
485 ATF_TC(powf_one_neg_x);
486 ATF_TC_HEAD(powf_one_neg_x, tc)
487 {
488 	atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0");
489 }
490 
491 ATF_TC_BODY(powf_one_neg_x, tc)
492 {
493 	const float infp = 1.0L / 0.0L;
494 	const float infn = -1.0L / 0.0L;
495 
496 	/*
497 	 * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
498 	 */
499 	ATF_REQUIRE(isinf(infp) != 0);
500 	ATF_REQUIRE(isinf(infn) != 0);
501 
502 	if (powf(-1.0, infp) != 1.0) {
503 		atf_tc_expect_fail("PR lib/45372");
504 		atf_tc_fail_nonfatal("powf(-1.0, +Inf) != 1.0");
505 	}
506 
507 	if (powf(-1.0, infn) != 1.0) {
508 		atf_tc_expect_fail("PR lib/45372");
509 		atf_tc_fail_nonfatal("powf(-1.0, -Inf) != 1.0");
510 	}
511 }
512 
513 ATF_TC(powf_one_pos_x);
514 ATF_TC_HEAD(powf_one_pos_x, tc)
515 {
516 	atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0");
517 }
518 
519 ATF_TC_BODY(powf_one_pos_x, tc)
520 {
521 	const float y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
522 	const float z = 0.0L / 0.0L;
523 	size_t i;
524 
525 	/*
526 	 * For any value of y (including NaN),
527 	 * if x is 1.0, 1.0 shall be returned.
528 	 */
529 	if (powf(1.0, z) != 1.0)
530 		atf_tc_fail_nonfatal("powf(1.0, NaN) != 1.0");
531 
532 	for (i = 0; i < __arraycount(y); i++) {
533 
534 		if (powf(1.0, y[i]) != 1.0)
535 			atf_tc_fail_nonfatal("powf(1.0, %0.01f) != 1.0", y[i]);
536 	}
537 }
538 
539 ATF_TC(powf_zero_x);
540 ATF_TC_HEAD(powf_zero_x, tc)
541 {
542 	atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE");
543 }
544 
545 ATF_TC_BODY(powf_zero_x, tc)
546 {
547 	float z;
548 
549 	/*
550 	 * If x is +0.0 or -0.0, y > 0, and y
551 	 * is an odd integer, x is returned.
552 	 */
553 	z = powf(+0.0, 3.0);
554 
555 	if (fabsf(z) > 0.0 || signbit(z) != 0)
556 		atf_tc_fail_nonfatal("powf(+0.0, 3.0) != +0.0");
557 
558 	z = powf(-0.0, 3.0);
559 
560 	if (fabsf(z) > 0.0 || signbit(z) == 0)
561 		atf_tc_fail_nonfatal("powf(-0.0, 3.0) != -0.0");
562 
563 	/*
564 	 * If y > 0 and not an odd integer,
565 	 * if x is +0.0 or -0.0, +0.0 is returned.
566 	 */
567 	z = powf(+0.0, 4.0);
568 
569 	if (fabsf(z) > 0.0 || signbit(z) != 0)
570 		atf_tc_fail_nonfatal("powf(+0.0, 4.0) != +0.0");
571 
572 	z = powf(-0.0, 4.0);
573 
574 	if (fabsf(z) > 0.0 || signbit(z) != 0)
575 		atf_tc_fail_nonfatal("powf(-0.0, 4.0) != +0.0");
576 
577 	/*
578 	 * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
579 	 * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
580 	 */
581 	z = powf(+0.0, -4.0);
582 
583 	if (z != HUGE_VALF) {
584 		atf_tc_expect_fail("PR port-amd64/45391");
585 		atf_tc_fail_nonfatal("powf(+0.0, -4.0) != HUGE_VALF");
586 	}
587 
588 	z = powf(-0.0, -4.0);
589 
590 	if (z != HUGE_VALF) {
591 		atf_tc_expect_fail("PR port-amd64/45391");
592 		atf_tc_fail_nonfatal("powf(-0.0, -4.0) != HUGE_VALF");
593 	}
594 
595 	z = powf(+0.0, -5.0);
596 
597 	if (z != HUGE_VALF) {
598 		atf_tc_expect_fail("PR port-amd64/45391");
599 		atf_tc_fail_nonfatal("powf(+0.0, -5.0) != HUGE_VALF");
600 	}
601 
602 	z = powf(-0.0, -5.0);
603 
604 	if (z != -HUGE_VALF)
605 		atf_tc_fail_nonfatal("powf(-0.0, -5.0) != -HUGE_VALF");
606 }
607 
608 ATF_TC(powf_zero_y);
609 ATF_TC_HEAD(powf_zero_y, tc)
610 {
611 	atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0");
612 }
613 
614 ATF_TC_BODY(powf_zero_y, tc)
615 {
616 	const float x[] =  { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
617 	const float z = 0.0L / 0.0L;
618 	size_t i;
619 
620 	/*
621 	 * For any value of x (including NaN),
622 	 * if y is +0.0 or -0.0, 1.0 is returned.
623 	 */
624 	if (powf(z, +0.0) != 1.0)
625 		atf_tc_fail_nonfatal("powf(NaN, +0.0) != 1.0");
626 
627 	if (powf(z, -0.0) != 1.0)
628 		atf_tc_fail_nonfatal("powf(NaN, -0.0) != 1.0");
629 
630 	for (i = 0; i < __arraycount(x); i++) {
631 
632 		if (powf(x[i], +0.0) != 1.0)
633 			atf_tc_fail_nonfatal("powf(%0.01f, +0.0) != 1.0",x[i]);
634 
635 		if (powf(x[i], -0.0) != 1.0)
636 			atf_tc_fail_nonfatal("powf(%0.01f, -0.0) != 1.0",x[i]);
637 	}
638 }
639 
640 ATF_TC(powf_near_one_x_huge_y);
641 ATF_TC_HEAD(powf_near_one_x_huge_y, tc)
642 {
643 	atf_tc_set_md_var(tc, "descr", "Test powf(->1, huge) != inf");
644 }
645 
646 ATF_TC_BODY(powf_near_one_x_huge_y, tc)
647 {
648 	const float x =  0x1.ffffeep-1f;   /*  9.999995e-01f */
649 	const float y = -0x1.000002p+27f;  /* -1.342177e+08f */
650 	const float e =  0x1.d53532p+103f; /*  1.858724e+31f */
651 	const float ulp = __FLT_EPSILON__;
652 	float z;
653 
654 	z = powf(x, y);
655 
656 	ATF_CHECK(isinf(z) == 0);
657 	ATF_CHECK(fabsf(z - e) <= 2 * ulp);
658 }
659 
660 
661 ATF_TP_ADD_TCS(tp)
662 {
663 
664 	ATF_TP_ADD_TC(tp, pow_nan_x);
665 	ATF_TP_ADD_TC(tp, pow_nan_y);
666 	ATF_TP_ADD_TC(tp, pow_inf_neg_x);
667 	ATF_TP_ADD_TC(tp, pow_inf_neg_y);
668 	ATF_TP_ADD_TC(tp, pow_inf_pos_x);
669 	ATF_TP_ADD_TC(tp, pow_inf_pos_y);
670 	ATF_TP_ADD_TC(tp, pow_one_neg_x);
671 	ATF_TP_ADD_TC(tp, pow_one_pos_x);
672 	ATF_TP_ADD_TC(tp, pow_zero_x);
673 	ATF_TP_ADD_TC(tp, pow_zero_y);
674 
675 	ATF_TP_ADD_TC(tp, powf_nan_x);
676 	ATF_TP_ADD_TC(tp, powf_nan_y);
677 	ATF_TP_ADD_TC(tp, powf_inf_neg_x);
678 	ATF_TP_ADD_TC(tp, powf_inf_neg_y);
679 	ATF_TP_ADD_TC(tp, powf_inf_pos_x);
680 	ATF_TP_ADD_TC(tp, powf_inf_pos_y);
681 	ATF_TP_ADD_TC(tp, powf_one_neg_x);
682 	ATF_TP_ADD_TC(tp, powf_one_pos_x);
683 	ATF_TP_ADD_TC(tp, powf_zero_x);
684 	ATF_TP_ADD_TC(tp, powf_zero_y);
685 	ATF_TP_ADD_TC(tp, powf_near_one_x_huge_y);
686 
687 	return atf_no_error();
688 }
689