1 /* $NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $ */
4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $");
41 static const int exps
[] = { 0, 1, -1, 100, -100 };
43 /* tests here do not require specific precision, so we just use double */
50 struct testcase test_vals
[] = {
51 { 0, 1.00085, 1.00085, 0 },
52 { 0, 0.99755, 0.99755, 0 },
53 { 0, -1.00085, -1.00085, 0 },
54 { 0, -0.99755, -0.99755, 0 },
55 { 1, 1.00085, 2.0* 1.00085, 0 },
56 { 1, 0.99755, 2.0* 0.99755, 0 },
57 { 1, -1.00085, 2.0* -1.00085, 0 },
58 { 1, -0.99755, 2.0* -0.99755, 0 },
61 * We could add more corner test cases here, but we would have to
62 * add some ifdefs for the exact format and use a reliable
63 * generator program - bail for now and only do trivial stuff above.
71 ATF_TC_HEAD(scalbn_val
, tc
)
73 atf_tc_set_md_var(tc
, "descr", "Test scalbn() for a few values");
76 ATF_TC_BODY(scalbn_val
, tc
)
78 const struct testcase
*tests
= test_vals
;
79 const size_t tcnt
= __arraycount(test_vals
);
83 for (i
= 0; i
< tcnt
; i
++) {
84 rv
= scalbn(tests
[i
].inval
, tests
[i
].exp
);
85 ATF_CHECK_EQ_MSG(errno
, tests
[i
].error
,
86 "test %zu: errno %d instead of %d", i
, errno
,
88 ATF_CHECK_MSG(fabs(rv
-tests
[i
].result
)<2.0*DBL_EPSILON
,
89 "test %zu: return value %g instead of %g (difference %g)",
90 i
, rv
, tests
[i
].result
, tests
[i
].result
-rv
);
95 ATF_TC_HEAD(scalbn_nan
, tc
)
97 atf_tc_set_md_var(tc
, "descr", "Test scalbn(NaN, n) == NaN");
100 ATF_TC_BODY(scalbn_nan
, tc
)
102 const double x
= 0.0L / 0.0L;
106 ATF_REQUIRE(isnan(x
) != 0);
108 for (i
= 0; i
< __arraycount(exps
); i
++) {
109 y
= scalbn(x
, exps
[i
]);
110 ATF_CHECK(isnan(y
) != 0);
114 ATF_TC(scalbn_inf_neg
);
115 ATF_TC_HEAD(scalbn_inf_neg
, tc
)
117 atf_tc_set_md_var(tc
, "descr", "Test scalbn(-Inf, n) == -Inf");
120 ATF_TC_BODY(scalbn_inf_neg
, tc
)
122 const double x
= -1.0L / 0.0L;
125 for (i
= 0; i
< __arraycount(exps
); i
++)
126 ATF_CHECK(scalbn(x
, exps
[i
]) == x
);
129 ATF_TC(scalbn_inf_pos
);
130 ATF_TC_HEAD(scalbn_inf_pos
, tc
)
132 atf_tc_set_md_var(tc
, "descr", "Test scalbn(+Inf, n) == +Inf");
135 ATF_TC_BODY(scalbn_inf_pos
, tc
)
137 const double x
= 1.0L / 0.0L;
140 for (i
= 0; i
< __arraycount(exps
); i
++)
141 ATF_CHECK(scalbn(x
, exps
[i
]) == x
);
144 ATF_TC(scalbn_ldexp
);
145 ATF_TC_HEAD(scalbn_ldexp
, tc
)
147 atf_tc_set_md_var(tc
, "descr", "Test scalbn(x, n) == ldexp(x, n)");
150 ATF_TC_BODY(scalbn_ldexp
, tc
)
153 const double x
= 2.91288191221812821;
157 for (i
= 0; i
< __arraycount(exps
); i
++) {
158 y
= scalbn(x
, exps
[i
]);
159 ATF_CHECK_MSG(y
== ldexp(x
, exps
[i
]), "test %zu: exponent=%d, "
160 "y=%g, expected %g (diff: %g)", i
, exps
[i
], y
,
161 ldexp(x
, exps
[i
]), y
- ldexp(x
, exps
[i
]));
166 ATF_TC(scalbn_zero_neg
);
167 ATF_TC_HEAD(scalbn_zero_neg
, tc
)
169 atf_tc_set_md_var(tc
, "descr", "Test scalbn(-0.0, n) == -0.0");
172 ATF_TC_BODY(scalbn_zero_neg
, tc
)
174 const double x
= -0.0L;
178 ATF_REQUIRE(signbit(x
) != 0);
180 for (i
= 0; i
< __arraycount(exps
); i
++) {
181 y
= scalbn(x
, exps
[i
]);
183 ATF_CHECK(signbit(y
) != 0);
187 ATF_TC(scalbn_zero_pos
);
188 ATF_TC_HEAD(scalbn_zero_pos
, tc
)
190 atf_tc_set_md_var(tc
, "descr", "Test scalbn(+0.0, n) == +0.0");
193 ATF_TC_BODY(scalbn_zero_pos
, tc
)
195 const double x
= 0.0L;
199 ATF_REQUIRE(signbit(x
) == 0);
201 for (i
= 0; i
< __arraycount(exps
); i
++) {
202 y
= scalbn(x
, exps
[i
]);
204 ATF_CHECK(signbit(y
) == 0);
212 ATF_TC_HEAD(scalbnf_val
, tc
)
214 atf_tc_set_md_var(tc
, "descr", "Test scalbnf() for a few values");
217 ATF_TC_BODY(scalbnf_val
, tc
)
219 const struct testcase
*tests
= test_vals
;
220 const size_t tcnt
= __arraycount(test_vals
);
224 for (i
= 0; i
< tcnt
; i
++) {
225 rv
= scalbnf(tests
[i
].inval
, tests
[i
].exp
);
226 ATF_CHECK_EQ_MSG(errno
, tests
[i
].error
,
227 "test %zu: errno %d instead of %d", i
, errno
,
229 ATF_CHECK_MSG(fabs(rv
-tests
[i
].result
)<2.0*FLT_EPSILON
,
230 "test %zu: return value %g instead of %g (difference %g)",
231 i
, rv
, tests
[i
].result
, tests
[i
].result
-rv
);
236 ATF_TC_HEAD(scalbnf_nan
, tc
)
238 atf_tc_set_md_var(tc
, "descr", "Test scalbnf(NaN, n) == NaN");
241 ATF_TC_BODY(scalbnf_nan
, tc
)
243 const float x
= 0.0L / 0.0L;
247 ATF_REQUIRE(isnan(x
) != 0);
249 for (i
= 0; i
< __arraycount(exps
); i
++) {
250 y
= scalbnf(x
, exps
[i
]);
251 ATF_CHECK(isnan(y
) != 0);
255 ATF_TC(scalbnf_inf_neg
);
256 ATF_TC_HEAD(scalbnf_inf_neg
, tc
)
258 atf_tc_set_md_var(tc
, "descr", "Test scalbnf(-Inf, n) == -Inf");
261 ATF_TC_BODY(scalbnf_inf_neg
, tc
)
263 const float x
= -1.0L / 0.0L;
266 for (i
= 0; i
< __arraycount(exps
); i
++)
267 ATF_CHECK(scalbnf(x
, exps
[i
]) == x
);
270 ATF_TC(scalbnf_inf_pos
);
271 ATF_TC_HEAD(scalbnf_inf_pos
, tc
)
273 atf_tc_set_md_var(tc
, "descr", "Test scalbnf(+Inf, n) == +Inf");
276 ATF_TC_BODY(scalbnf_inf_pos
, tc
)
278 const float x
= 1.0L / 0.0L;
281 for (i
= 0; i
< __arraycount(exps
); i
++)
282 ATF_CHECK(scalbnf(x
, exps
[i
]) == x
);
285 ATF_TC(scalbnf_ldexpf
);
286 ATF_TC_HEAD(scalbnf_ldexpf
, tc
)
288 atf_tc_set_md_var(tc
, "descr", "Test scalbnf(x, n) == ldexpf(x, n)");
291 ATF_TC_BODY(scalbnf_ldexpf
, tc
)
294 const float x
= 2.91288191221812821;
298 for (i
= 0; i
< __arraycount(exps
); i
++) {
299 y
= scalbnf(x
, exps
[i
]);
300 ATF_CHECK_MSG(y
== ldexpf(x
, exps
[i
]),
301 "test %zu: exponent=%d, y=%g ldexpf returns %g (diff: %g)",
302 i
, exps
[i
], y
, ldexpf(x
, exps
[i
]), y
-ldexpf(x
, exps
[i
]));
307 ATF_TC(scalbnf_zero_neg
);
308 ATF_TC_HEAD(scalbnf_zero_neg
, tc
)
310 atf_tc_set_md_var(tc
, "descr", "Test scalbnf(-0.0, n) == -0.0");
313 ATF_TC_BODY(scalbnf_zero_neg
, tc
)
315 const float x
= -0.0L;
319 ATF_REQUIRE(signbit(x
) != 0);
321 for (i
= 0; i
< __arraycount(exps
); i
++) {
322 y
= scalbnf(x
, exps
[i
]);
324 ATF_CHECK(signbit(y
) != 0);
328 ATF_TC(scalbnf_zero_pos
);
329 ATF_TC_HEAD(scalbnf_zero_pos
, tc
)
331 atf_tc_set_md_var(tc
, "descr", "Test scalbnf(+0.0, n) == +0.0");
334 ATF_TC_BODY(scalbnf_zero_pos
, tc
)
336 const float x
= 0.0L;
340 ATF_REQUIRE(signbit(x
) == 0);
342 for (i
= 0; i
< __arraycount(exps
); i
++) {
343 y
= scalbnf(x
, exps
[i
]);
345 ATF_CHECK(signbit(y
) == 0);
353 ATF_TC_HEAD(scalbnl_val
, tc
)
355 atf_tc_set_md_var(tc
, "descr", "Test scalbnl() for a few values");
358 ATF_TC_BODY(scalbnl_val
, tc
)
360 #ifndef __HAVE_LONG_DOUBLE
361 atf_tc_skip("Requires long double support");
363 const struct testcase
*tests
= test_vals
;
364 const size_t tcnt
= __arraycount(test_vals
);
368 for (i
= 0; i
< tcnt
; i
++) {
369 rv
= scalbnl(tests
[i
].inval
, tests
[i
].exp
);
370 ATF_CHECK_EQ_MSG(errno
, tests
[i
].error
,
371 "test %zu: errno %d instead of %d", i
, errno
,
373 ATF_CHECK_MSG(fabsl(rv
-(long double)tests
[i
].result
)<2.0*LDBL_EPSILON
,
374 "test %zu: return value %Lg instead of %Lg (difference %Lg)",
375 i
, rv
, (long double)tests
[i
].result
, (long double)tests
[i
].result
-rv
);
381 ATF_TC_HEAD(scalbnl_nan
, tc
)
383 atf_tc_set_md_var(tc
, "descr", "Test scalbnl(NaN, n) == NaN");
386 ATF_TC_BODY(scalbnl_nan
, tc
)
388 #ifndef __HAVE_LONG_DOUBLE
389 atf_tc_skip("Requires long double support");
391 const long double x
= 0.0L / 0.0L;
396 atf_tc_expect_fail("PR lib/45362");
397 atf_tc_fail("(0.0L / 0.0L) != NaN");
400 for (i
= 0; i
< __arraycount(exps
); i
++) {
401 y
= scalbnl(x
, exps
[i
]);
402 ATF_CHECK(isnan(y
) != 0);
407 ATF_TC(scalbnl_inf_neg
);
408 ATF_TC_HEAD(scalbnl_inf_neg
, tc
)
410 atf_tc_set_md_var(tc
, "descr", "Test scalbnl(-Inf, n) == -Inf");
413 ATF_TC_BODY(scalbnl_inf_neg
, tc
)
415 #ifndef __HAVE_LONG_DOUBLE
416 atf_tc_skip("Requires long double support");
418 const long double x
= -1.0L / 0.0L;
421 for (i
= 0; i
< __arraycount(exps
); i
++)
422 ATF_CHECK(scalbnl(x
, exps
[i
]) == x
);
426 ATF_TC(scalbnl_inf_pos
);
427 ATF_TC_HEAD(scalbnl_inf_pos
, tc
)
429 atf_tc_set_md_var(tc
, "descr", "Test scalbnl(+Inf, n) == +Inf");
432 ATF_TC_BODY(scalbnl_inf_pos
, tc
)
434 #ifndef __HAVE_LONG_DOUBLE
435 atf_tc_skip("Requires long double support");
437 const long double x
= 1.0L / 0.0L;
440 for (i
= 0; i
< __arraycount(exps
); i
++)
441 ATF_CHECK(scalbnl(x
, exps
[i
]) == x
);
445 ATF_TC(scalbnl_zero_neg
);
446 ATF_TC_HEAD(scalbnl_zero_neg
, tc
)
448 atf_tc_set_md_var(tc
, "descr", "Test scalbnl(-0.0, n) == -0.0");
451 ATF_TC_BODY(scalbnl_zero_neg
, tc
)
453 #ifndef __HAVE_LONG_DOUBLE
454 atf_tc_skip("Requires long double support");
456 const long double x
= -0.0L;
460 ATF_REQUIRE(signbit(x
) != 0);
462 for (i
= 0; i
< __arraycount(exps
); i
++) {
463 y
= scalbnl(x
, exps
[i
]);
465 ATF_CHECK(signbit(y
) != 0);
470 ATF_TC(scalbnl_zero_pos
);
471 ATF_TC_HEAD(scalbnl_zero_pos
, tc
)
473 atf_tc_set_md_var(tc
, "descr", "Test scalbnl(+0.0, n) == +0.0");
476 ATF_TC_BODY(scalbnl_zero_pos
, tc
)
478 #ifndef __HAVE_LONG_DOUBLE
479 atf_tc_skip("Requires long double support");
481 const long double x
= 0.0L;
485 ATF_REQUIRE(signbit(x
) == 0);
487 for (i
= 0; i
< __arraycount(exps
); i
++) {
488 y
= scalbnl(x
, exps
[i
]);
490 ATF_CHECK(signbit(y
) == 0);
498 ATF_TP_ADD_TC(tp
, scalbn_val
);
499 ATF_TP_ADD_TC(tp
, scalbn_nan
);
500 ATF_TP_ADD_TC(tp
, scalbn_inf_neg
);
501 ATF_TP_ADD_TC(tp
, scalbn_inf_pos
);
502 ATF_TP_ADD_TC(tp
, scalbn_ldexp
);
503 ATF_TP_ADD_TC(tp
, scalbn_zero_neg
);
504 ATF_TP_ADD_TC(tp
, scalbn_zero_pos
);
506 ATF_TP_ADD_TC(tp
, scalbnf_val
);
507 ATF_TP_ADD_TC(tp
, scalbnf_nan
);
508 ATF_TP_ADD_TC(tp
, scalbnf_inf_neg
);
509 ATF_TP_ADD_TC(tp
, scalbnf_inf_pos
);
510 ATF_TP_ADD_TC(tp
, scalbnf_ldexpf
);
511 ATF_TP_ADD_TC(tp
, scalbnf_zero_neg
);
512 ATF_TP_ADD_TC(tp
, scalbnf_zero_pos
);
514 ATF_TP_ADD_TC(tp
, scalbnl_val
);
515 ATF_TP_ADD_TC(tp
, scalbnl_nan
);
516 ATF_TP_ADD_TC(tp
, scalbnl_inf_neg
);
517 ATF_TP_ADD_TC(tp
, scalbnl_inf_pos
);
518 /* ATF_TP_ADD_TC(tp, scalbnl_ldexp); */
519 ATF_TP_ADD_TC(tp
, scalbnl_zero_neg
);
520 ATF_TP_ADD_TC(tp
, scalbnl_zero_pos
);
522 return atf_no_error();