]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/netbsd-tests/lib/libm/t_scalbn.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / netbsd-tests / lib / libm / t_scalbn.c
1 /* $NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin 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_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $");
33
34 #include <math.h>
35 #include <limits.h>
36 #include <float.h>
37 #include <errno.h>
38
39 #include <atf-c.h>
40
41 static const int exps[] = { 0, 1, -1, 100, -100 };
42
43 /* tests here do not require specific precision, so we just use double */
44 struct testcase {
45         int exp;
46         double inval;
47         double result;
48         int error;
49 };
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 },
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
67 /*
68  * scalbn(3)
69  */
70 ATF_TC(scalbn_val);
71 ATF_TC_HEAD(scalbn_val, tc)
72 {
73         atf_tc_set_md_var(tc, "descr", "Test scalbn() for a few values");
74 }
75
76 ATF_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 #ifdef __FreeBSD__
85                 errno = 0;
86 #endif
87                 rv = scalbn(tests[i].inval, tests[i].exp);
88                 ATF_CHECK_EQ_MSG(errno, tests[i].error,
89                     "test %zu: errno %d instead of %d", i, errno,
90                     tests[i].error);
91                 ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*DBL_EPSILON,
92                     "test %zu: return value %g instead of %g (difference %g)",
93                     i, rv, tests[i].result, tests[i].result-rv);
94         }
95 }
96
97 ATF_TC(scalbn_nan);
98 ATF_TC_HEAD(scalbn_nan, tc)
99 {
100         atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN");
101 }
102
103 ATF_TC_BODY(scalbn_nan, tc)
104 {
105         const double x = 0.0L / 0.0L;
106         double y;
107         size_t i;
108
109         ATF_REQUIRE(isnan(x) != 0);
110
111         for (i = 0; i < __arraycount(exps); i++) {
112                 y = scalbn(x, exps[i]);
113                 ATF_CHECK(isnan(y) != 0);
114         }
115 }
116
117 ATF_TC(scalbn_inf_neg);
118 ATF_TC_HEAD(scalbn_inf_neg, tc)
119 {
120         atf_tc_set_md_var(tc, "descr", "Test scalbn(-Inf, n) == -Inf");
121 }
122
123 ATF_TC_BODY(scalbn_inf_neg, tc)
124 {
125         const double x = -1.0L / 0.0L;
126         size_t i;
127
128         for (i = 0; i < __arraycount(exps); i++)
129                 ATF_CHECK(scalbn(x, exps[i]) == x);
130 }
131
132 ATF_TC(scalbn_inf_pos);
133 ATF_TC_HEAD(scalbn_inf_pos, tc)
134 {
135         atf_tc_set_md_var(tc, "descr", "Test scalbn(+Inf, n) == +Inf");
136 }
137
138 ATF_TC_BODY(scalbn_inf_pos, tc)
139 {
140         const double x = 1.0L / 0.0L;
141         size_t i;
142
143         for (i = 0; i < __arraycount(exps); i++)
144                 ATF_CHECK(scalbn(x, exps[i]) == x);
145 }
146
147 ATF_TC(scalbn_ldexp);
148 ATF_TC_HEAD(scalbn_ldexp, tc)
149 {
150         atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)");
151 }
152
153 ATF_TC_BODY(scalbn_ldexp, tc)
154 {
155 #if FLT_RADIX == 2
156         const double x = 2.91288191221812821;
157         double y;
158         size_t i;
159
160         for (i = 0; i < __arraycount(exps); i++) {
161                 y = scalbn(x, exps[i]);
162                 ATF_CHECK_MSG(y == ldexp(x, exps[i]), "test %zu: exponent=%d, "
163                     "y=%g, expected %g (diff: %g)", i, exps[i], y, 
164                     ldexp(x, exps[i]), y - ldexp(x, exps[i]));
165         }
166 #endif
167 }
168
169 ATF_TC(scalbn_zero_neg);
170 ATF_TC_HEAD(scalbn_zero_neg, tc)
171 {
172         atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0");
173 }
174
175 ATF_TC_BODY(scalbn_zero_neg, tc)
176 {
177         const double x = -0.0L;
178         double y;
179         size_t i;
180
181         ATF_REQUIRE(signbit(x) != 0);
182
183         for (i = 0; i < __arraycount(exps); i++) {
184                 y = scalbn(x, exps[i]);
185                 ATF_CHECK(x == y);
186                 ATF_CHECK(signbit(y) != 0);
187         }
188 }
189
190 ATF_TC(scalbn_zero_pos);
191 ATF_TC_HEAD(scalbn_zero_pos, tc)
192 {
193         atf_tc_set_md_var(tc, "descr", "Test scalbn(+0.0, n) == +0.0");
194 }
195
196 ATF_TC_BODY(scalbn_zero_pos, tc)
197 {
198         const double x = 0.0L;
199         double y;
200         size_t i;
201
202         ATF_REQUIRE(signbit(x) == 0);
203
204         for (i = 0; i < __arraycount(exps); i++) {
205                 y = scalbn(x, exps[i]);
206                 ATF_CHECK(x == y);
207                 ATF_CHECK(signbit(y) == 0);
208         }
209 }
210
211 /*
212  * scalbnf(3)
213  */
214 ATF_TC(scalbnf_val);
215 ATF_TC_HEAD(scalbnf_val, tc)
216 {
217         atf_tc_set_md_var(tc, "descr", "Test scalbnf() for a few values");
218 }
219
220 ATF_TC_BODY(scalbnf_val, tc)
221 {
222         const struct testcase *tests = test_vals;
223         const size_t tcnt = __arraycount(test_vals);
224         size_t i;
225         double rv;
226
227         for (i = 0; i < tcnt; i++) {
228 #ifdef __FreeBSD__
229                 errno = 0;
230 #endif
231                 rv = scalbnf(tests[i].inval, tests[i].exp);
232                 ATF_CHECK_EQ_MSG(errno, tests[i].error,
233                     "test %zu: errno %d instead of %d", i, errno,
234                     tests[i].error);
235                 ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*FLT_EPSILON,
236                     "test %zu: return value %g instead of %g (difference %g)",
237                     i, rv, tests[i].result, tests[i].result-rv);
238         }
239 }
240
241 ATF_TC(scalbnf_nan);
242 ATF_TC_HEAD(scalbnf_nan, tc)
243 {
244         atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN");
245 }
246
247 ATF_TC_BODY(scalbnf_nan, tc)
248 {
249         const float x = 0.0L / 0.0L;
250         float y;
251         size_t i;
252
253         ATF_REQUIRE(isnan(x) != 0);
254
255         for (i = 0; i < __arraycount(exps); i++) {
256                 y = scalbnf(x, exps[i]);
257                 ATF_CHECK(isnan(y) != 0);
258         }
259 }
260
261 ATF_TC(scalbnf_inf_neg);
262 ATF_TC_HEAD(scalbnf_inf_neg, tc)
263 {
264         atf_tc_set_md_var(tc, "descr", "Test scalbnf(-Inf, n) == -Inf");
265 }
266
267 ATF_TC_BODY(scalbnf_inf_neg, tc)
268 {
269         const float x = -1.0L / 0.0L;
270         size_t i;
271
272         for (i = 0; i < __arraycount(exps); i++)
273                 ATF_CHECK(scalbnf(x, exps[i]) == x);
274 }
275
276 ATF_TC(scalbnf_inf_pos);
277 ATF_TC_HEAD(scalbnf_inf_pos, tc)
278 {
279         atf_tc_set_md_var(tc, "descr", "Test scalbnf(+Inf, n) == +Inf");
280 }
281
282 ATF_TC_BODY(scalbnf_inf_pos, tc)
283 {
284         const float x = 1.0L / 0.0L;
285         size_t i;
286
287         for (i = 0; i < __arraycount(exps); i++)
288                 ATF_CHECK(scalbnf(x, exps[i]) == x);
289 }
290
291 ATF_TC(scalbnf_ldexpf);
292 ATF_TC_HEAD(scalbnf_ldexpf, tc)
293 {
294         atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)");
295 }
296
297 ATF_TC_BODY(scalbnf_ldexpf, tc)
298 {
299 #if FLT_RADIX == 2
300         const float x = 2.91288191221812821;
301         float y;
302         size_t i;
303
304         for (i = 0; i < __arraycount(exps); i++) {
305                 y = scalbnf(x, exps[i]);
306                 ATF_CHECK_MSG(y == ldexpf(x, exps[i]),
307                     "test %zu: exponent=%d, y=%g ldexpf returns %g (diff: %g)",
308                     i, exps[i], y, ldexpf(x, exps[i]), y-ldexpf(x, exps[i]));
309         }
310 #endif
311 }
312
313 ATF_TC(scalbnf_zero_neg);
314 ATF_TC_HEAD(scalbnf_zero_neg, tc)
315 {
316         atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0");
317 }
318
319 ATF_TC_BODY(scalbnf_zero_neg, tc)
320 {
321         const float x = -0.0L;
322         float y;
323         size_t i;
324
325         ATF_REQUIRE(signbit(x) != 0);
326
327         for (i = 0; i < __arraycount(exps); i++) {
328                 y = scalbnf(x, exps[i]);
329                 ATF_CHECK(x == y);
330                 ATF_CHECK(signbit(y) != 0);
331         }
332 }
333
334 ATF_TC(scalbnf_zero_pos);
335 ATF_TC_HEAD(scalbnf_zero_pos, tc)
336 {
337         atf_tc_set_md_var(tc, "descr", "Test scalbnf(+0.0, n) == +0.0");
338 }
339
340 ATF_TC_BODY(scalbnf_zero_pos, tc)
341 {
342         const float x = 0.0L;
343         float y;
344         size_t i;
345
346         ATF_REQUIRE(signbit(x) == 0);
347
348         for (i = 0; i < __arraycount(exps); i++) {
349                 y = scalbnf(x, exps[i]);
350                 ATF_CHECK(x == y);
351                 ATF_CHECK(signbit(y) == 0);
352         }
353 }
354
355 /*
356  * scalbnl(3)
357  */
358 ATF_TC(scalbnl_val);
359 ATF_TC_HEAD(scalbnl_val, tc)
360 {
361         atf_tc_set_md_var(tc, "descr", "Test scalbnl() for a few values");
362 }
363
364 ATF_TC_BODY(scalbnl_val, tc)
365 {
366 #ifndef __HAVE_LONG_DOUBLE
367         atf_tc_skip("Requires long double support");
368 #else
369         const struct testcase *tests = test_vals;
370         const size_t tcnt = __arraycount(test_vals);
371         size_t i;
372         long double rv;
373
374         for (i = 0; i < tcnt; i++) {
375 #ifdef __FreeBSD__
376                 errno = 0;
377 #endif
378                 rv = scalbnl(tests[i].inval, tests[i].exp);
379                 ATF_CHECK_EQ_MSG(errno, tests[i].error,
380                     "test %zu: errno %d instead of %d", i, errno,
381                     tests[i].error);
382                 ATF_CHECK_MSG(fabsl(rv-(long double)tests[i].result)<2.0*LDBL_EPSILON,
383                     "test %zu: return value %Lg instead of %Lg (difference %Lg)",
384                     i, rv, (long double)tests[i].result, (long double)tests[i].result-rv);
385         }
386 #endif
387 }
388
389 ATF_TC(scalbnl_nan);
390 ATF_TC_HEAD(scalbnl_nan, tc)
391 {
392         atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN");
393 }
394
395 ATF_TC_BODY(scalbnl_nan, tc)
396 {
397 #ifndef __HAVE_LONG_DOUBLE
398         atf_tc_skip("Requires long double support");
399 #else
400         const long double x = 0.0L / 0.0L;
401         long double y;
402         size_t i;
403
404         if (isnan(x) == 0) {
405                 atf_tc_expect_fail("PR lib/45362");
406                 atf_tc_fail("(0.0L / 0.0L) != NaN");
407         }
408
409         for (i = 0; i < __arraycount(exps); i++) {
410                 y = scalbnl(x, exps[i]);
411                 ATF_CHECK(isnan(y) != 0);
412         }
413 #endif
414 }
415
416 ATF_TC(scalbnl_inf_neg);
417 ATF_TC_HEAD(scalbnl_inf_neg, tc)
418 {
419         atf_tc_set_md_var(tc, "descr", "Test scalbnl(-Inf, n) == -Inf");
420 }
421
422 ATF_TC_BODY(scalbnl_inf_neg, tc)
423 {
424 #ifndef __HAVE_LONG_DOUBLE
425         atf_tc_skip("Requires long double support");
426 #else
427         const long double x = -1.0L / 0.0L;
428         size_t i;
429
430         for (i = 0; i < __arraycount(exps); i++)
431                 ATF_CHECK(scalbnl(x, exps[i]) == x);
432 #endif
433 }
434
435 ATF_TC(scalbnl_inf_pos);
436 ATF_TC_HEAD(scalbnl_inf_pos, tc)
437 {
438         atf_tc_set_md_var(tc, "descr", "Test scalbnl(+Inf, n) == +Inf");
439 }
440
441 ATF_TC_BODY(scalbnl_inf_pos, tc)
442 {
443 #ifndef __HAVE_LONG_DOUBLE
444         atf_tc_skip("Requires long double support");
445 #else
446         const long double x = 1.0L / 0.0L;
447         size_t i;
448
449         for (i = 0; i < __arraycount(exps); i++)
450                 ATF_CHECK(scalbnl(x, exps[i]) == x);
451 #endif
452 }
453
454 ATF_TC(scalbnl_zero_neg);
455 ATF_TC_HEAD(scalbnl_zero_neg, tc)
456 {
457         atf_tc_set_md_var(tc, "descr", "Test scalbnl(-0.0, n) == -0.0");
458 }
459
460 ATF_TC_BODY(scalbnl_zero_neg, tc)
461 {
462 #ifndef __HAVE_LONG_DOUBLE
463         atf_tc_skip("Requires long double support");
464 #else
465         const long double x = -0.0L;
466         long double y;
467         size_t i;
468
469         ATF_REQUIRE(signbit(x) != 0);
470
471         for (i = 0; i < __arraycount(exps); i++) {
472                 y = scalbnl(x, exps[i]);
473                 ATF_CHECK(x == y);
474                 ATF_CHECK(signbit(y) != 0);
475         }
476 #endif
477 }
478
479 ATF_TC(scalbnl_zero_pos);
480 ATF_TC_HEAD(scalbnl_zero_pos, tc)
481 {
482         atf_tc_set_md_var(tc, "descr", "Test scalbnl(+0.0, n) == +0.0");
483 }
484
485 ATF_TC_BODY(scalbnl_zero_pos, tc)
486 {
487 #ifndef __HAVE_LONG_DOUBLE
488         atf_tc_skip("Requires long double support");
489 #else
490         const long double x = 0.0L;
491         long double y;
492         size_t i;
493
494         ATF_REQUIRE(signbit(x) == 0);
495
496         for (i = 0; i < __arraycount(exps); i++) {
497                 y = scalbnl(x, exps[i]);
498                 ATF_CHECK(x == y);
499                 ATF_CHECK(signbit(y) == 0);
500         }
501 #endif
502 }
503
504 ATF_TP_ADD_TCS(tp)
505 {
506
507         ATF_TP_ADD_TC(tp, scalbn_val);
508         ATF_TP_ADD_TC(tp, scalbn_nan);
509         ATF_TP_ADD_TC(tp, scalbn_inf_neg);
510         ATF_TP_ADD_TC(tp, scalbn_inf_pos);
511         ATF_TP_ADD_TC(tp, scalbn_ldexp);
512         ATF_TP_ADD_TC(tp, scalbn_zero_neg);
513         ATF_TP_ADD_TC(tp, scalbn_zero_pos);
514
515         ATF_TP_ADD_TC(tp, scalbnf_val);
516         ATF_TP_ADD_TC(tp, scalbnf_nan);
517         ATF_TP_ADD_TC(tp, scalbnf_inf_neg);
518         ATF_TP_ADD_TC(tp, scalbnf_inf_pos);
519         ATF_TP_ADD_TC(tp, scalbnf_ldexpf);
520         ATF_TP_ADD_TC(tp, scalbnf_zero_neg);
521         ATF_TP_ADD_TC(tp, scalbnf_zero_pos);
522
523         ATF_TP_ADD_TC(tp, scalbnl_val);
524         ATF_TP_ADD_TC(tp, scalbnl_nan);
525         ATF_TP_ADD_TC(tp, scalbnl_inf_neg);
526         ATF_TP_ADD_TC(tp, scalbnl_inf_pos);
527 /*      ATF_TP_ADD_TC(tp, scalbnl_ldexp);       */
528         ATF_TP_ADD_TC(tp, scalbnl_zero_neg);
529         ATF_TP_ADD_TC(tp, scalbnl_zero_pos);
530
531         return atf_no_error();
532 }