Mon May 20 12:21:42 2013 UTC ()
Add a few test cases to test "ordinary" values with the various scalbn
variants. While there, make some spuriously failing tests print out the
broken values on failure.


(martin)
diff -r1.7 -r1.8 src/tests/lib/libm/t_scalbn.c

cvs diff -r1.7 -r1.8 src/tests/lib/libm/t_scalbn.c (expand / switch to unified diff)

--- src/tests/lib/libm/t_scalbn.c 2011/09/13 07:07:32 1.7
+++ src/tests/lib/libm/t_scalbn.c 2013/05/20 12:21:42 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: t_scalbn.c,v 1.7 2011/09/13 07:07:32 jruoho Exp $ */ 1/* $NetBSD: t_scalbn.c,v 1.8 2013/05/20 12:21:42 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jukka Ruohonen. 8 * by Jukka Ruohonen.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -19,38 +19,88 @@ @@ -19,38 +19,88 @@
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 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 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 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__RCSID("$NetBSD: t_scalbn.c,v 1.7 2011/09/13 07:07:32 jruoho Exp $"); 32__RCSID("$NetBSD: t_scalbn.c,v 1.8 2013/05/20 12:21:42 martin Exp $");
33 33
34#include <math.h> 34#include <math.h>
35#include <limits.h> 35#include <limits.h>
 36#include <float.h>
 37#include <errno.h>
36 38
37#include <atf-c.h> 39#include <atf-c.h>
38 40
39static const int exps[] = { 0, 1, -1, 100, -100 }; 41static const int exps[] = { 0, 1, -1, 100, -100 };
40 42
 43/* tests here do not require specific precision, so we just use double */
 44struct testcase {
 45 int exp;
 46 double inval;
 47 double result;
 48 int error;
 49};
 50struct 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 },
 59
 60 /*
 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.
 64 */
 65};
 66
41/* 67/*
42 * scalbn(3) 68 * scalbn(3)
43 */ 69 */
 70ATF_TC(scalbn_val);
 71ATF_TC_HEAD(scalbn_val, tc)
 72{
 73 atf_tc_set_md_var(tc, "descr", "Test scalbn() for a few values");
 74}
 75
 76ATF_TC_BODY(scalbn_val, tc)
 77{
 78 const struct testcase *tests = test_vals;
 79 const size_t tcnt = __arraycount(test_vals);
 80 size_t i;
 81 double rv;
 82
 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,
 87 tests[i].error);
 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);
 91 }
 92}
 93
44ATF_TC(scalbn_nan); 94ATF_TC(scalbn_nan);
45ATF_TC_HEAD(scalbn_nan, tc) 95ATF_TC_HEAD(scalbn_nan, tc)
46{ 96{
47 atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN"); 97 atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN");
48} 98}
49 99
50ATF_TC_BODY(scalbn_nan, tc) 100ATF_TC_BODY(scalbn_nan, tc)
51{ 101{
52#ifndef __vax__ 102#ifndef __vax__
53 const double x = 0.0L / 0.0L; 103 const double x = 0.0L / 0.0L;
54 double y; 104 double y;
55 size_t i; 105 size_t i;
56 106
@@ -103,27 +153,29 @@ ATF_TC_HEAD(scalbn_ldexp, tc) @@ -103,27 +153,29 @@ ATF_TC_HEAD(scalbn_ldexp, tc)
103 atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)"); 153 atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)");
104} 154}
105 155
106ATF_TC_BODY(scalbn_ldexp, tc) 156ATF_TC_BODY(scalbn_ldexp, tc)
107{ 157{
108#ifndef __vax__ 158#ifndef __vax__
109#if FLT_RADIX == 2 159#if FLT_RADIX == 2
110 const double x = 2.91288191221812821; 160 const double x = 2.91288191221812821;
111 double y; 161 double y;
112 size_t i; 162 size_t i;
113 163
114 for (i = 0; i < __arraycount(exps); i++) { 164 for (i = 0; i < __arraycount(exps); i++) {
115 y = scalbn(x, exps[i]); 165 y = scalbn(x, exps[i]);
116 ATF_CHECK(y == ldexp(x, exps[i])); 166 ATF_CHECK_MSG(y == ldexp(x, exps[i]), "test %zu: exponent=%d, "
 167 "y=%g, expected %g (diff: %g)", i, exps[i], y,
 168 ldexp(x, exps[i]), y - ldexp(x, exps[i]));
117 } 169 }
118#endif 170#endif
119#endif 171#endif
120} 172}
121 173
122ATF_TC(scalbn_zero_neg); 174ATF_TC(scalbn_zero_neg);
123ATF_TC_HEAD(scalbn_zero_neg, tc) 175ATF_TC_HEAD(scalbn_zero_neg, tc)
124{ 176{
125 atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0"); 177 atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0");
126} 178}
127 179
128ATF_TC_BODY(scalbn_zero_neg, tc) 180ATF_TC_BODY(scalbn_zero_neg, tc)
129{ 181{
@@ -158,26 +210,50 @@ ATF_TC_BODY(scalbn_zero_pos, tc) @@ -158,26 +210,50 @@ ATF_TC_BODY(scalbn_zero_pos, tc)
158 ATF_REQUIRE(signbit(x) == 0); 210 ATF_REQUIRE(signbit(x) == 0);
159 211
160 for (i = 0; i < __arraycount(exps); i++) { 212 for (i = 0; i < __arraycount(exps); i++) {
161 y = scalbn(x, exps[i]); 213 y = scalbn(x, exps[i]);
162 ATF_CHECK(x == y); 214 ATF_CHECK(x == y);
163 ATF_CHECK(signbit(y) == 0); 215 ATF_CHECK(signbit(y) == 0);
164 } 216 }
165#endif 217#endif
166} 218}
167 219
168/* 220/*
169 * scalbnf(3) 221 * scalbnf(3)
170 */ 222 */
 223ATF_TC(scalbnf_val);
 224ATF_TC_HEAD(scalbnf_val, tc)
 225{
 226 atf_tc_set_md_var(tc, "descr", "Test scalbnf() for a few values");
 227}
 228
 229ATF_TC_BODY(scalbnf_val, tc)
 230{
 231 const struct testcase *tests = test_vals;
 232 const size_t tcnt = __arraycount(test_vals);
 233 size_t i;
 234 double rv;
 235
 236 for (i = 0; i < tcnt; i++) {
 237 rv = scalbnf(tests[i].inval, tests[i].exp);
 238 ATF_CHECK_EQ_MSG(errno, tests[i].error,
 239 "test %zu: errno %d instead of %d", i, errno,
 240 tests[i].error);
 241 ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*FLT_EPSILON,
 242 "test %zu: return value %g instead of %g (difference %g)",
 243 i, rv, tests[i].result, tests[i].result-rv);
 244 }
 245}
 246
171ATF_TC(scalbnf_nan); 247ATF_TC(scalbnf_nan);
172ATF_TC_HEAD(scalbnf_nan, tc) 248ATF_TC_HEAD(scalbnf_nan, tc)
173{ 249{
174 atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN"); 250 atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN");
175} 251}
176 252
177ATF_TC_BODY(scalbnf_nan, tc) 253ATF_TC_BODY(scalbnf_nan, tc)
178{ 254{
179#ifndef __vax__ 255#ifndef __vax__
180 const float x = 0.0L / 0.0L; 256 const float x = 0.0L / 0.0L;
181 float y; 257 float y;
182 size_t i; 258 size_t i;
183 259
@@ -230,27 +306,29 @@ ATF_TC_HEAD(scalbnf_ldexpf, tc) @@ -230,27 +306,29 @@ ATF_TC_HEAD(scalbnf_ldexpf, tc)
230 atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)"); 306 atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)");
231} 307}
232 308
233ATF_TC_BODY(scalbnf_ldexpf, tc) 309ATF_TC_BODY(scalbnf_ldexpf, tc)
234{ 310{
235#ifndef __vax__ 311#ifndef __vax__
236#if FLT_RADIX == 2 312#if FLT_RADIX == 2
237 const float x = 2.91288191221812821; 313 const float x = 2.91288191221812821;
238 float y; 314 float y;
239 size_t i; 315 size_t i;
240 316
241 for (i = 0; i < __arraycount(exps); i++) { 317 for (i = 0; i < __arraycount(exps); i++) {
242 y = scalbnf(x, exps[i]); 318 y = scalbnf(x, exps[i]);
243 ATF_CHECK(y == ldexpf(x, exps[i])); 319 ATF_CHECK_MSG(y == ldexpf(x, exps[i]),
 320 "test %zu: exponent=%d, y=%g ldexpf returns %g (diff: %g)",
 321 i, exps[i], y, ldexpf(x, exps[i]), y-ldexpf(x, exps[i]));
244 } 322 }
245#endif 323#endif
246#endif 324#endif
247} 325}
248 326
249ATF_TC(scalbnf_zero_neg); 327ATF_TC(scalbnf_zero_neg);
250ATF_TC_HEAD(scalbnf_zero_neg, tc) 328ATF_TC_HEAD(scalbnf_zero_neg, tc)
251{ 329{
252 atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0"); 330 atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0");
253} 331}
254 332
255ATF_TC_BODY(scalbnf_zero_neg, tc) 333ATF_TC_BODY(scalbnf_zero_neg, tc)
256{ 334{
@@ -285,26 +363,54 @@ ATF_TC_BODY(scalbnf_zero_pos, tc) @@ -285,26 +363,54 @@ ATF_TC_BODY(scalbnf_zero_pos, tc)
285 ATF_REQUIRE(signbit(x) == 0); 363 ATF_REQUIRE(signbit(x) == 0);
286 364
287 for (i = 0; i < __arraycount(exps); i++) { 365 for (i = 0; i < __arraycount(exps); i++) {
288 y = scalbnf(x, exps[i]); 366 y = scalbnf(x, exps[i]);
289 ATF_CHECK(x == y); 367 ATF_CHECK(x == y);
290 ATF_CHECK(signbit(y) == 0); 368 ATF_CHECK(signbit(y) == 0);
291 } 369 }
292#endif 370#endif
293} 371}
294 372
295/* 373/*
296 * scalbnl(3) 374 * scalbnl(3)
297 */ 375 */
 376ATF_TC(scalbnl_val);
 377ATF_TC_HEAD(scalbnl_val, tc)
 378{
 379 atf_tc_set_md_var(tc, "descr", "Test scalbnl() for a few values");
 380}
 381
 382ATF_TC_BODY(scalbnl_val, tc)
 383{
 384#ifndef __HAVE_LONG_DOUBLE
 385 atf_tc_skip("Requires long double support");
 386#else
 387 const struct testcase *tests = test_vals;
 388 const size_t tcnt = __arraycount(test_vals);
 389 size_t i;
 390 long double rv;
 391
 392 for (i = 0; i < tcnt; i++) {
 393 rv = scalbnl(tests[i].inval, tests[i].exp);
 394 ATF_CHECK_EQ_MSG(errno, tests[i].error,
 395 "test %zu: errno %d instead of %d", i, errno,
 396 tests[i].error);
 397 ATF_CHECK_MSG(fabsl(rv-(long double)tests[i].result)<2.0*LDBL_EPSILON,
 398 "test %zu: return value %Lg instead of %Lg (difference %Lg)",
 399 i, rv, (long double)tests[i].result, (long double)tests[i].result-rv);
 400 }
 401#endif
 402}
 403
298ATF_TC(scalbnl_nan); 404ATF_TC(scalbnl_nan);
299ATF_TC_HEAD(scalbnl_nan, tc) 405ATF_TC_HEAD(scalbnl_nan, tc)
300{ 406{
301 atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN"); 407 atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN");
302} 408}
303 409
304ATF_TC_BODY(scalbnl_nan, tc) 410ATF_TC_BODY(scalbnl_nan, tc)
305{ 411{
306#ifndef __vax__ 412#ifndef __vax__
307#ifndef __HAVE_LONG_DOUBLE 413#ifndef __HAVE_LONG_DOUBLE
308 atf_tc_skip("Requires long double support"); 414 atf_tc_skip("Requires long double support");
309#else 415#else
310 const long double x = 0.0L / 0.0L; 416 const long double x = 0.0L / 0.0L;
@@ -413,36 +519,39 @@ ATF_TC_BODY(scalbnl_zero_pos, tc) @@ -413,36 +519,39 @@ ATF_TC_BODY(scalbnl_zero_pos, tc)
413 519
414 for (i = 0; i < __arraycount(exps); i++) { 520 for (i = 0; i < __arraycount(exps); i++) {
415 y = scalbnl(x, exps[i]); 521 y = scalbnl(x, exps[i]);
416 ATF_CHECK(x == y); 522 ATF_CHECK(x == y);
417 ATF_CHECK(signbit(y) == 0); 523 ATF_CHECK(signbit(y) == 0);
418 } 524 }
419#endif 525#endif
420#endif 526#endif
421} 527}
422 528
423ATF_TP_ADD_TCS(tp) 529ATF_TP_ADD_TCS(tp)
424{ 530{
425 531
 532 ATF_TP_ADD_TC(tp, scalbn_val);
426 ATF_TP_ADD_TC(tp, scalbn_nan); 533 ATF_TP_ADD_TC(tp, scalbn_nan);
427 ATF_TP_ADD_TC(tp, scalbn_inf_neg); 534 ATF_TP_ADD_TC(tp, scalbn_inf_neg);
428 ATF_TP_ADD_TC(tp, scalbn_inf_pos); 535 ATF_TP_ADD_TC(tp, scalbn_inf_pos);
429 ATF_TP_ADD_TC(tp, scalbn_ldexp); 536 ATF_TP_ADD_TC(tp, scalbn_ldexp);
430 ATF_TP_ADD_TC(tp, scalbn_zero_neg); 537 ATF_TP_ADD_TC(tp, scalbn_zero_neg);
431 ATF_TP_ADD_TC(tp, scalbn_zero_pos); 538 ATF_TP_ADD_TC(tp, scalbn_zero_pos);
432 539
 540 ATF_TP_ADD_TC(tp, scalbnf_val);
433 ATF_TP_ADD_TC(tp, scalbnf_nan); 541 ATF_TP_ADD_TC(tp, scalbnf_nan);
434 ATF_TP_ADD_TC(tp, scalbnf_inf_neg); 542 ATF_TP_ADD_TC(tp, scalbnf_inf_neg);
435 ATF_TP_ADD_TC(tp, scalbnf_inf_pos); 543 ATF_TP_ADD_TC(tp, scalbnf_inf_pos);
436 ATF_TP_ADD_TC(tp, scalbnf_ldexpf); 544 ATF_TP_ADD_TC(tp, scalbnf_ldexpf);
437 ATF_TP_ADD_TC(tp, scalbnf_zero_neg); 545 ATF_TP_ADD_TC(tp, scalbnf_zero_neg);
438 ATF_TP_ADD_TC(tp, scalbnf_zero_pos); 546 ATF_TP_ADD_TC(tp, scalbnf_zero_pos);
439 547
 548 ATF_TP_ADD_TC(tp, scalbnl_val);
440 ATF_TP_ADD_TC(tp, scalbnl_nan); 549 ATF_TP_ADD_TC(tp, scalbnl_nan);
441 ATF_TP_ADD_TC(tp, scalbnl_inf_neg); 550 ATF_TP_ADD_TC(tp, scalbnl_inf_neg);
442 ATF_TP_ADD_TC(tp, scalbnl_inf_pos); 551 ATF_TP_ADD_TC(tp, scalbnl_inf_pos);
443/* ATF_TP_ADD_TC(tp, scalbnl_ldexp); */ 552/* ATF_TP_ADD_TC(tp, scalbnl_ldexp); */
444 ATF_TP_ADD_TC(tp, scalbnl_zero_neg); 553 ATF_TP_ADD_TC(tp, scalbnl_zero_neg);
445 ATF_TP_ADD_TC(tp, scalbnl_zero_pos); 554 ATF_TP_ADD_TC(tp, scalbnl_zero_pos);
446 555
447 return atf_no_error(); 556 return atf_no_error();
448} 557}