1 /* $NetBSD: t_pow.c,v 1.6 2024/06/09 16:53:25 riastradh 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.6 2024/06/09 16:53:25 riastradh Exp $");
33
34 #include <atf-c.h>
35 #include <math.h>
36
37 /*
38 * pow(3)
39 */
40 ATF_TC(pow_nan_x);
ATF_TC_HEAD(pow_nan_x,tc)41 ATF_TC_HEAD(pow_nan_x, tc)
42 {
43 atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN");
44 }
45
ATF_TC_BODY(pow_nan_x,tc)46 ATF_TC_BODY(pow_nan_x, tc)
47 {
48 const volatile double x = 0.0 / 0.0;
49 const double z = pow(x, 2.0);
50
51 ATF_CHECK_MSG(isnan(z), "z=%a", z);
52 }
53
54 ATF_TC(pow_nan_y);
ATF_TC_HEAD(pow_nan_y,tc)55 ATF_TC_HEAD(pow_nan_y, tc)
56 {
57 atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN");
58 }
59
ATF_TC_BODY(pow_nan_y,tc)60 ATF_TC_BODY(pow_nan_y, tc)
61 {
62 const volatile double y = 0.0 / 0.0;
63 const double z = pow(2.0, y);
64
65 ATF_CHECK_MSG(isnan(z), "z=%a", z);
66 }
67
68 ATF_TC(pow_inf_neg_x);
ATF_TC_HEAD(pow_inf_neg_x,tc)69 ATF_TC_HEAD(pow_inf_neg_x, tc)
70 {
71 atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0");
72 }
73
ATF_TC_BODY(pow_inf_neg_x,tc)74 ATF_TC_BODY(pow_inf_neg_x, tc)
75 {
76 const volatile double x = -1.0 / 0.0;
77 double z;
78
79 /*
80 * If y is odd, y > 0, and x is -Inf, -Inf is returned.
81 * If y is even, y > 0, and x is -Inf, +Inf is returned.
82 */
83 z = pow(x, 3.0);
84 ATF_CHECK_MSG(isinf(z), "x=%a z=%s=%a", x, "pow(x, 3.0)", z);
85 ATF_CHECK_MSG(signbit(z) != 0, "x=%a z=%s=%a", x, "pow(x, 3.0)", z);
86
87 z = pow(x, 4.0);
88 ATF_CHECK_MSG(isinf(z), "x=%a z=%s=%a", x, "pow(x, 4.0)", z);
89 ATF_CHECK_MSG(signbit(z) == 0, "x=%a z=%s=%a", x, "pow(x, 4.0)", z);
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 ATF_CHECK_MSG(fabs(z) == 0.0, "x=%a z=%s=%a", x, "pow(x, -3.0)", z);
97 ATF_CHECK_MSG(signbit(z) != 0, "x=%a z=%s=%a", x, "pow(x, -3.0)", z);
98
99 z = pow(x, -4.0);
100 ATF_CHECK_MSG(fabs(z) == 0.0, "x=%a z=%s=%a", x, "pow(x, -4.0)", z);
101 ATF_CHECK_MSG(signbit(z) == 0, "x=%a z=%s=%a", x, "pow(x, -4.0)", z);
102 }
103
104 ATF_TC(pow_inf_neg_y);
ATF_TC_HEAD(pow_inf_neg_y,tc)105 ATF_TC_HEAD(pow_inf_neg_y, tc)
106 {
107 atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0");
108 }
109
ATF_TC_BODY(pow_inf_neg_y,tc)110 ATF_TC_BODY(pow_inf_neg_y, tc)
111 {
112 const volatile double y = -1.0 / 0.0;
113 double z;
114
115 /*
116 * If |x| < 1 and y is -Inf, +Inf is returned.
117 * If |x| > 1 and y is -Inf, +0.0 is returned.
118 */
119 z = pow(0.1, y);
120 ATF_CHECK_MSG(isinf(z), "y=%a z=%s=%a", y, "pow(0.1, y)", z);
121 ATF_CHECK_MSG(signbit(z) == 0, "y=%a z=%s=%a", y, "pow(0.1, y)", z);
122
123 z = pow(1.1, y);
124 ATF_CHECK_MSG(fabs(z) == 0.0, "y=%a z=%s=%a", y, "pow(1.1, y)", z);
125 ATF_CHECK_MSG(signbit(z) == 0, "y=%a z=%s=%a", y, "pow(1.1, y)", z);
126 }
127
128 ATF_TC(pow_inf_pos_x);
ATF_TC_HEAD(pow_inf_pos_x,tc)129 ATF_TC_HEAD(pow_inf_pos_x, tc)
130 {
131 atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0");
132 }
133
ATF_TC_BODY(pow_inf_pos_x,tc)134 ATF_TC_BODY(pow_inf_pos_x, tc)
135 {
136 const volatile double x = 1.0 / 0.0;
137 double z;
138
139 /*
140 * For y < 0, if x is +Inf, +0.0 is returned.
141 * For y > 0, if x is +Inf, +Inf is returned.
142 */
143 z = pow(x, -2.0);
144 ATF_CHECK_MSG(fabs(z) == 0.0, "x=%a z=%s=%a", x, "pow(x, -2.0)", z);
145 ATF_CHECK_MSG(signbit(z) == 0, "x=%a z=%s=%a", x, "pow(x, -2.0)", z);
146
147 z = pow(x, 2.0);
148 ATF_CHECK_MSG(isinf(z), "x=%a z=%s=%a", x, "pow(x, 2.0)", z);
149 ATF_CHECK_MSG(signbit(z) == 0, "x=%a z=%s=%a", x, "pow(x, 2.0)", z);
150 }
151
152 ATF_TC(pow_inf_pos_y);
ATF_TC_HEAD(pow_inf_pos_y,tc)153 ATF_TC_HEAD(pow_inf_pos_y, tc)
154 {
155 atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0");
156 }
157
ATF_TC_BODY(pow_inf_pos_y,tc)158 ATF_TC_BODY(pow_inf_pos_y, tc)
159 {
160 const volatile double y = 1.0 / 0.0;
161 double z;
162
163 /*
164 * If |x| < 1 and y is +Inf, +0.0 is returned.
165 * If |x| > 1 and y is +Inf, +Inf is returned.
166 */
167 z = pow(0.1, y);
168 ATF_CHECK_MSG(fabs(z) == 0, "y=%a z=%s=%a", y, "pow(0.1, y)", z);
169 ATF_CHECK_MSG(signbit(z) == 0, "y=%a z=%s=%a", y, "pow(0.1, y)", z);
170
171 z = pow(1.1, y);
172 ATF_CHECK_MSG(isinf(z), "y=%a z=%s=%a", y, "pow(1.1, y)", z);
173 ATF_CHECK_MSG(signbit(z) == 0, "y=%a z=%s=%a", y, "pow(1.1, y)", z);
174 }
175
176 ATF_TC(pow_one_neg_x);
ATF_TC_HEAD(pow_one_neg_x,tc)177 ATF_TC_HEAD(pow_one_neg_x, tc)
178 {
179 atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0");
180 }
181
ATF_TC_BODY(pow_one_neg_x,tc)182 ATF_TC_BODY(pow_one_neg_x, tc)
183 {
184 const volatile double infp = 1.0 / 0.0;
185 const volatile double infn = -1.0 / 0.0;
186 double z;
187
188 /*
189 * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
190 */
191 ATF_REQUIRE_MSG(isinf(infp), "infp=%a", infp);
192 ATF_REQUIRE_MSG(isinf(infn), "infn=%a", infn);
193
194 ATF_CHECK_EQ_MSG((z = pow(-1.0, infp)), 1.0, "z=%a", z);
195 ATF_CHECK_EQ_MSG((z = pow(-1.0, infn)), 1.0, "z=%a", z);
196 }
197
198 ATF_TC(pow_one_pos_x);
ATF_TC_HEAD(pow_one_pos_x,tc)199 ATF_TC_HEAD(pow_one_pos_x, tc)
200 {
201 atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0");
202 }
203
ATF_TC_BODY(pow_one_pos_x,tc)204 ATF_TC_BODY(pow_one_pos_x, tc)
205 {
206 const volatile double y[] =
207 { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
208 const volatile double z = 0.0 / 0.0;
209 size_t i;
210
211 /*
212 * For any value of y (including NaN),
213 * if x is 1.0, 1.0 shall be returned.
214 */
215 ATF_CHECK_EQ_MSG(pow(1.0, z), 1.0, "z=%a pow(1.0, z)=%a",
216 z, pow(1.0, z));
217
218 for (i = 0; i < __arraycount(y); i++) {
219 ATF_CHECK_EQ_MSG(pow(1.0, y[i]), 1.0,
220 "i=%zu y[i]=%a pow(1.0, y[i])=%a",
221 i, y[i], pow(1.0, y[i]));
222 }
223 }
224
225 ATF_TC(pow_zero_x);
ATF_TC_HEAD(pow_zero_x,tc)226 ATF_TC_HEAD(pow_zero_x, tc)
227 {
228 atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE");
229 }
230
ATF_TC_BODY(pow_zero_x,tc)231 ATF_TC_BODY(pow_zero_x, tc)
232 {
233 double z;
234
235 /*
236 * If x is +0.0 or -0.0, y > 0, and y
237 * is an odd integer, x is returned.
238 */
239 z = pow(+0.0, 3.0);
240 ATF_CHECK_MSG(fabs(z) == 0.0, "z=%a", z);
241 ATF_CHECK_MSG(signbit(z) == 0, "z=%a", z);
242
243 z = pow(-0.0, 3.0);
244 ATF_CHECK_MSG(fabs(z) == 0.0, "z=%a", z);
245 ATF_CHECK_MSG(signbit(z) != 0, "z=%a", z);
246
247 /*
248 * If y > 0 and not an odd integer,
249 * if x is +0.0 or -0.0, +0.0 is returned.
250 */
251 z = pow(+0.0, 4.0);
252 ATF_CHECK_MSG(fabs(z) == 0.0, "z=%a", z);
253 ATF_CHECK_MSG(signbit(z) == 0, "z=%a", z);
254
255 z = pow(-0.0, 4.0);
256 ATF_CHECK_MSG(fabs(z) == 0.0, "z=%a", z);
257 ATF_CHECK_MSG(signbit(z) == 0, "z=%a", z);
258
259 /*
260 * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
261 * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
262 */
263 z = pow(+0.0, -4.0);
264 ATF_CHECK_EQ_MSG(z, HUGE_VAL, "z=%a", z);
265
266 z = pow(-0.0, -4.0);
267 ATF_CHECK_EQ_MSG(z, HUGE_VAL, "z=%a", z);
268
269 z = pow(+0.0, -5.0);
270 ATF_CHECK_EQ_MSG(z, HUGE_VAL, "z=%a", z);
271
272 z = pow(-0.0, -5.0);
273 ATF_CHECK_EQ_MSG(z, -HUGE_VAL, "z=%a", z);
274 }
275
276 ATF_TC(pow_zero_y);
ATF_TC_HEAD(pow_zero_y,tc)277 ATF_TC_HEAD(pow_zero_y, tc)
278 {
279 atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0");
280 }
281
ATF_TC_BODY(pow_zero_y,tc)282 ATF_TC_BODY(pow_zero_y, tc)
283 {
284 const volatile double x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
285 const volatile double z = 0.0 / 0.0;
286 size_t i;
287
288 /*
289 * For any value of x (including NaN),
290 * if y is +0.0 or -0.0, 1.0 is returned.
291 */
292 ATF_CHECK_EQ_MSG(pow(z, +0.0), 1.0, "z=%a pow(z, +0.0)=%a",
293 z, pow(z, +0.0));
294 ATF_CHECK_EQ_MSG(pow(z, -0.0), 1.0, "z=%a pow(z, -0.0)=%a",
295 z, pow(z, -0.0));
296
297 for (i = 0; i < __arraycount(x); i++) {
298 ATF_CHECK_EQ_MSG(pow(x[i], +0.0), 1.0,
299 "i=%zu pow(%a, +0.0)=%a", i, x[i], pow(x[i], +0.0));
300 ATF_CHECK_EQ_MSG(pow(x[i], -0.0), 1.0,
301 "i=%zu pow(%a, -0.0)=%a", i, x[i], pow(x[i], -0.0));
302 }
303 }
304
305 /*
306 * powf(3)
307 */
308 ATF_TC(powf_nan_x);
ATF_TC_HEAD(powf_nan_x,tc)309 ATF_TC_HEAD(powf_nan_x, tc)
310 {
311 atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN");
312 }
313
ATF_TC_BODY(powf_nan_x,tc)314 ATF_TC_BODY(powf_nan_x, tc)
315 {
316 const volatile float x = 0.0f / 0.0f;
317 const float z = powf(x, 2.0f);
318
319 ATF_CHECK_MSG(isnanf(z), "z=%a", z);
320 }
321
322 ATF_TC(powf_nan_y);
ATF_TC_HEAD(powf_nan_y,tc)323 ATF_TC_HEAD(powf_nan_y, tc)
324 {
325 atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN");
326 }
327
ATF_TC_BODY(powf_nan_y,tc)328 ATF_TC_BODY(powf_nan_y, tc)
329 {
330 const volatile float y = 0.0f / 0.0f;
331 const float z = powf(2.0f, y);
332
333 ATF_CHECK_MSG(isnanf(z), "z=%a", z);
334 }
335
336 ATF_TC(powf_inf_neg_x);
ATF_TC_HEAD(powf_inf_neg_x,tc)337 ATF_TC_HEAD(powf_inf_neg_x, tc)
338 {
339 atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0");
340 }
341
ATF_TC_BODY(powf_inf_neg_x,tc)342 ATF_TC_BODY(powf_inf_neg_x, tc)
343 {
344 const volatile float x = -1.0f / 0.0f;
345 float z;
346
347 /*
348 * If y is odd, y > 0, and x is -Inf, -Inf is returned.
349 * If y is even, y > 0, and x is -Inf, +Inf is returned.
350 */
351 z = powf(x, 3.0);
352 ATF_CHECK_MSG(isinf(z), "x=%a z=%s=%a", x, "powf(x, 3.0)", z);
353 ATF_CHECK_MSG(signbit(z) != 0, "x=%a z=%s=%a", x, "powf(x, 3.0)", z);
354
355 z = powf(x, 4.0);
356 ATF_CHECK_MSG(isinf(z), "x=%a z=%s=%a", x, "powf(x, 4.0)", z);
357 ATF_CHECK_MSG(signbit(z) == 0, "x=%a z=%s=%a", x, "powf(x, 4.0)", z);
358
359 /*
360 * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
361 * If y is even, y < 0, and x is -Inf, +0.0 is returned.
362 */
363 z = powf(x, -3.0);
364 ATF_CHECK_MSG(fabsf(z) == 0.0, "x=%a z=%s=%a", x, "powf(x, -3.0)", z);
365 ATF_CHECK_MSG(signbit(z) != 0, "x=%a z=%s=%a", x, "powf(x, -3.0)", z);
366
367 z = powf(x, -4.0);
368 ATF_CHECK_MSG(fabsf(z) == 0.0, "x=%a z=%s=%a", x, "powf(x, -4.0)", z);
369 ATF_CHECK_MSG(signbit(z) == 0, "x=%a z=%s=%a", x, "powf(x, -4.0)", z);
370 }
371
372 ATF_TC(powf_inf_neg_y);
ATF_TC_HEAD(powf_inf_neg_y,tc)373 ATF_TC_HEAD(powf_inf_neg_y, tc)
374 {
375 atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0");
376 }
377
ATF_TC_BODY(powf_inf_neg_y,tc)378 ATF_TC_BODY(powf_inf_neg_y, tc)
379 {
380 const volatile float y = -1.0f / 0.0f;
381 float z;
382
383 /*
384 * If |x| < 1 and y is -Inf, +Inf is returned.
385 * If |x| > 1 and y is -Inf, +0.0 is returned.
386 */
387 z = powf(0.1, y);
388 ATF_CHECK_MSG(isinf(z), "y=%a z=%s=%a", y, "powf(0.1, y)", z);
389 ATF_CHECK_MSG(signbit(z) == 0, "y=%a z=%s=%a", y, "powf(0.1, y)", z);
390
391 z = powf(1.1, y);
392 ATF_CHECK_MSG(fabsf(z) == 0.0, "y=%a z=%s=%a", y, "powf(1.1, y)", z);
393 ATF_CHECK_MSG(signbit(z) == 0, "y=%a z=%s=%a", y, "powf(1.1, y)", z);
394 }
395
396 ATF_TC(powf_inf_pos_x);
ATF_TC_HEAD(powf_inf_pos_x,tc)397 ATF_TC_HEAD(powf_inf_pos_x, tc)
398 {
399 atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0");
400 }
401
ATF_TC_BODY(powf_inf_pos_x,tc)402 ATF_TC_BODY(powf_inf_pos_x, tc)
403 {
404 const volatile float x = 1.0f / 0.0f;
405 float z;
406
407 /*
408 * For y < 0, if x is +Inf, +0.0 is returned.
409 * For y > 0, if x is +Inf, +Inf is returned.
410 */
411 z = powf(x, -2.0);
412 ATF_CHECK_MSG(fabsf(z) == 0.0, "x=%a z=%s=%a", x, "powf(x, -2.0)", z);
413 ATF_CHECK_MSG(signbit(z) == 0, "x=%a z=%s=%a", x, "powf(x, -2.0)", z);
414
415 z = powf(x, 2.0);
416 ATF_CHECK_MSG(isinf(z), "x=%a z=%s=%a", x, "powf(x, 2.0)", z);
417 ATF_CHECK_MSG(signbit(z) == 0, "x=%a z=%s=%a", x, "powf(x, 2.0)", z);
418 }
419
420 ATF_TC(powf_inf_pos_y);
ATF_TC_HEAD(powf_inf_pos_y,tc)421 ATF_TC_HEAD(powf_inf_pos_y, tc)
422 {
423 atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0");
424 }
425
ATF_TC_BODY(powf_inf_pos_y,tc)426 ATF_TC_BODY(powf_inf_pos_y, tc)
427 {
428 const float y = 1.0L / 0.0L;
429 float z;
430
431 /*
432 * If |x| < 1 and y is +Inf, +0.0 is returned.
433 * If |x| > 1 and y is +Inf, +Inf is returned.
434 */
435 z = powf(0.1, y);
436 ATF_CHECK_MSG(fabsf(z) == 0.0, "y=%a z=%s=%a", y, "powf(0.1, y)", z);
437 ATF_CHECK_MSG(signbit(z) == 0, "y=%a z=%s=%a", y, "powf(0.1, y)", z);
438
439 z = powf(1.1, y);
440 ATF_CHECK_MSG(isinf(z), "y=%a z=%s=%a", y, "powf(1.1, y)", z);
441 ATF_CHECK_MSG(signbit(z) == 0, "y=%a z=%s=%a", y, "powf(1.1, y)", z);
442 }
443
444 ATF_TC(powf_one_neg_x);
ATF_TC_HEAD(powf_one_neg_x,tc)445 ATF_TC_HEAD(powf_one_neg_x, tc)
446 {
447 atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0");
448 }
449
ATF_TC_BODY(powf_one_neg_x,tc)450 ATF_TC_BODY(powf_one_neg_x, tc)
451 {
452 const volatile float infp = 1.0f / 0.0f;
453 const volatile float infn = -1.0f / 0.0f;
454 double z;
455
456 /*
457 * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
458 */
459 ATF_REQUIRE_MSG(isinf(infp), "infp=%a", infp);
460 ATF_REQUIRE_MSG(isinf(infn), "infn=%a", infn);
461
462 ATF_CHECK_EQ_MSG((z = powf(-1.0, infp)), 1.0, "z=%a", z);
463 ATF_CHECK_EQ_MSG((z = powf(-1.0, infn)), 1.0, "z=%a", z);
464 }
465
466 ATF_TC(powf_one_pos_x);
ATF_TC_HEAD(powf_one_pos_x,tc)467 ATF_TC_HEAD(powf_one_pos_x, tc)
468 {
469 atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0");
470 }
471
ATF_TC_BODY(powf_one_pos_x,tc)472 ATF_TC_BODY(powf_one_pos_x, tc)
473 {
474 const volatile float y[] =
475 { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
476 const volatile float z = 0.0f / 0.0f;
477 size_t i;
478
479 /*
480 * For any value of y (including NaN),
481 * if x is 1.0, 1.0 shall be returned.
482 */
483 ATF_CHECK_EQ_MSG(powf(1.0, z), 1.0, "z=%a powf(1.0, z)=%a",
484 z, powf(1.0, z));
485
486 for (i = 0; i < __arraycount(y); i++) {
487 ATF_CHECK_EQ_MSG(powf(1.0, y[i]), 1.0,
488 "i=%zu y[i]=%a powf(1.0, y[i])=%a",
489 i, y[i], powf(1.0, y[i]));
490 }
491 }
492
493 ATF_TC(powf_zero_x);
ATF_TC_HEAD(powf_zero_x,tc)494 ATF_TC_HEAD(powf_zero_x, tc)
495 {
496 atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE");
497 }
498
ATF_TC_BODY(powf_zero_x,tc)499 ATF_TC_BODY(powf_zero_x, tc)
500 {
501 float z;
502
503 /*
504 * If x is +0.0 or -0.0, y > 0, and y
505 * is an odd integer, x is returned.
506 */
507 z = powf(+0.0, 3.0);
508 ATF_CHECK_MSG(fabsf(z) == 0.0, "z=%a", z);
509 ATF_CHECK_MSG(signbit(z) == 0, "z=%a", z);
510
511 z = powf(-0.0, 3.0);
512 ATF_CHECK_MSG(fabsf(z) == 0.0, "z=%a", z);
513 ATF_CHECK_MSG(signbit(z) != 0, "z=%a", z);
514
515 /*
516 * If y > 0 and not an odd integer,
517 * if x is +0.0 or -0.0, +0.0 is returned.
518 */
519 z = powf(+0.0, 4.0);
520 ATF_CHECK_MSG(fabsf(z) == 0.0, "z=%a", z);
521 ATF_CHECK_MSG(signbit(z) == 0, "z=%a", z);
522
523 z = powf(-0.0, 4.0);
524 ATF_CHECK_MSG(fabsf(z) == 0.0, "z=%a", z);
525 ATF_CHECK_MSG(signbit(z) == 0, "z=%a", z);
526
527 /*
528 * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
529 * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
530 */
531 z = powf(+0.0, -4.0);
532 ATF_CHECK_EQ_MSG(z, HUGE_VALF, "z=%a", z);
533
534 z = powf(-0.0, -4.0);
535 ATF_CHECK_EQ_MSG(z, HUGE_VALF, "z=%a", z);
536
537 z = powf(+0.0, -5.0);
538 ATF_CHECK_EQ_MSG(z, HUGE_VALF, "z=%a", z);
539
540 z = powf(-0.0, -5.0);
541 ATF_CHECK_EQ_MSG(z, -HUGE_VALF, "z=%a", z);
542 }
543
544 ATF_TC(powf_zero_y);
ATF_TC_HEAD(powf_zero_y,tc)545 ATF_TC_HEAD(powf_zero_y, tc)
546 {
547 atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0");
548 }
549
ATF_TC_BODY(powf_zero_y,tc)550 ATF_TC_BODY(powf_zero_y, tc)
551 {
552 const volatile float x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
553 const volatile float z = 0.0f / 0.0f;
554 size_t i;
555
556 /*
557 * For any value of x (including NaN),
558 * if y is +0.0 or -0.0, 1.0 is returned.
559 */
560 ATF_CHECK_EQ_MSG(powf(z, +0.0), 1.0, "z=%a powf(z, +0.0)=%a",
561 z, powf(z, +0.0));
562 ATF_CHECK_EQ_MSG(powf(z, -0.0), 1.0, "z=%a powf(z, -0.0)=%a",
563 z, powf(z, -0.0));
564
565 for (i = 0; i < __arraycount(x); i++) {
566 ATF_CHECK_EQ_MSG(powf(x[i], +0.0), 1.0,
567 "i=%zu powf(%a, +0.0)=%a", i, x[i], powf(x[i], +0.0));
568 ATF_CHECK_EQ_MSG(powf(x[i], -0.0), 1.0,
569 "i=%zu powf(%a, -0.0)=%a", i, x[i], powf(x[i], -0.0));
570 }
571 }
572
ATF_TP_ADD_TCS(tp)573 ATF_TP_ADD_TCS(tp)
574 {
575
576 ATF_TP_ADD_TC(tp, pow_nan_x);
577 ATF_TP_ADD_TC(tp, pow_nan_y);
578 ATF_TP_ADD_TC(tp, pow_inf_neg_x);
579 ATF_TP_ADD_TC(tp, pow_inf_neg_y);
580 ATF_TP_ADD_TC(tp, pow_inf_pos_x);
581 ATF_TP_ADD_TC(tp, pow_inf_pos_y);
582 ATF_TP_ADD_TC(tp, pow_one_neg_x);
583 ATF_TP_ADD_TC(tp, pow_one_pos_x);
584 ATF_TP_ADD_TC(tp, pow_zero_x);
585 ATF_TP_ADD_TC(tp, pow_zero_y);
586
587 ATF_TP_ADD_TC(tp, powf_nan_x);
588 ATF_TP_ADD_TC(tp, powf_nan_y);
589 ATF_TP_ADD_TC(tp, powf_inf_neg_x);
590 ATF_TP_ADD_TC(tp, powf_inf_neg_y);
591 ATF_TP_ADD_TC(tp, powf_inf_pos_x);
592 ATF_TP_ADD_TC(tp, powf_inf_pos_y);
593 ATF_TP_ADD_TC(tp, powf_one_neg_x);
594 ATF_TP_ADD_TC(tp, powf_one_pos_x);
595 ATF_TP_ADD_TC(tp, powf_zero_x);
596 ATF_TP_ADD_TC(tp, powf_zero_y);
597
598 return atf_no_error();
599 }
600