1/* $NetBSD: t_scalbn.c,v 1.6 2011/09/13 06:50:41 jruoho 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.6 2011/09/13 06:50:41 jruoho Exp $");
33
34#include <math.h>
35#include <limits.h>
36
37#include <atf-c.h>
38
39static const int exps[] = { 0, 1, -1, 100, -100 };
40
41/*
42 * scalbn(3)
43 */
44ATF_TC(scalbn_nan);
45ATF_TC_HEAD(scalbn_nan, tc)
46{
47	atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN");
48}
49
50ATF_TC_BODY(scalbn_nan, tc)
51{
52#ifndef __vax__
53	const double x = 0.0L / 0.0L;
54	double y;
55	size_t i;
56
57	ATF_REQUIRE(isnan(x) != 0);
58
59	for (i = 0; i < __arraycount(exps); i++) {
60		y = scalbn(x, exps[i]);
61		ATF_CHECK(isnan(y) != 0);
62	}
63#endif
64}
65
66ATF_TC(scalbn_inf_neg);
67ATF_TC_HEAD(scalbn_inf_neg, tc)
68{
69	atf_tc_set_md_var(tc, "descr", "Test scalbn(-Inf, n) == -Inf");
70}
71
72ATF_TC_BODY(scalbn_inf_neg, tc)
73{
74#ifndef __vax__
75	const double x = -1.0L / 0.0L;
76	size_t i;
77
78	for (i = 0; i < __arraycount(exps); i++)
79		ATF_CHECK(scalbn(x, exps[i]) == x);
80#endif
81}
82
83ATF_TC(scalbn_inf_pos);
84ATF_TC_HEAD(scalbn_inf_pos, tc)
85{
86	atf_tc_set_md_var(tc, "descr", "Test scalbn(+Inf, n) == +Inf");
87}
88
89ATF_TC_BODY(scalbn_inf_pos, tc)
90{
91#ifndef __vax__
92	const double x = 1.0L / 0.0L;
93	size_t i;
94
95	for (i = 0; i < __arraycount(exps); i++)
96		ATF_CHECK(scalbn(x, exps[i]) == x);
97#endif
98}
99
100ATF_TC(scalbn_ldexp);
101ATF_TC_HEAD(scalbn_ldexp, tc)
102{
103	atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)");
104}
105
106ATF_TC_BODY(scalbn_ldexp, tc)
107{
108#ifndef __vax__
109#if FLT_RADIX == 2
110	const double x = 2.91288191221812821;
111	double y;
112	size_t i;
113
114	for (i = 0; i < __arraycount(exps); i++) {
115		y = scalbn(x, exps[i]);
116		ATF_CHECK(y == ldexp(x, exps[i]));
117	}
118#endif
119#endif
120}
121
122ATF_TC(scalbn_zero_neg);
123ATF_TC_HEAD(scalbn_zero_neg, tc)
124{
125	atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0");
126}
127
128ATF_TC_BODY(scalbn_zero_neg, tc)
129{
130#ifndef __vax__
131	const double x = -0.0L;
132	double y;
133	size_t i;
134
135	ATF_REQUIRE(signbit(x) != 0);
136
137	for (i = 0; i < __arraycount(exps); i++) {
138		y = scalbn(x, exps[i]);
139		ATF_CHECK(x == y);
140		ATF_CHECK(signbit(y) != 0);
141	}
142#endif
143}
144
145ATF_TC(scalbn_zero_pos);
146ATF_TC_HEAD(scalbn_zero_pos, tc)
147{
148	atf_tc_set_md_var(tc, "descr", "Test scalbn(+0.0, n) == +0.0");
149}
150
151ATF_TC_BODY(scalbn_zero_pos, tc)
152{
153#ifndef __vax__
154	const double x = 0.0L;
155	double y;
156	size_t i;
157
158	ATF_REQUIRE(signbit(x) == 0);
159
160	for (i = 0; i < __arraycount(exps); i++) {
161		y = scalbn(x, exps[i]);
162		ATF_CHECK(x == y);
163		ATF_CHECK(signbit(y) == 0);
164	}
165#endif
166}
167
168/*
169 * scalbnf(3)
170 */
171ATF_TC(scalbnf_nan);
172ATF_TC_HEAD(scalbnf_nan, tc)
173{
174	atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN");
175}
176
177ATF_TC_BODY(scalbnf_nan, tc)
178{
179#ifndef __vax__
180	const float x = 0.0L / 0.0L;
181	float y;
182	size_t i;
183
184	ATF_REQUIRE(isnan(x) != 0);
185
186	for (i = 0; i < __arraycount(exps); i++) {
187		y = scalbnf(x, exps[i]);
188		ATF_CHECK(isnan(y) != 0);
189	}
190#endif
191}
192
193ATF_TC(scalbnf_inf_neg);
194ATF_TC_HEAD(scalbnf_inf_neg, tc)
195{
196	atf_tc_set_md_var(tc, "descr", "Test scalbnf(-Inf, n) == -Inf");
197}
198
199ATF_TC_BODY(scalbnf_inf_neg, tc)
200{
201#ifndef __vax__
202	const float x = -1.0L / 0.0L;
203	size_t i;
204
205	for (i = 0; i < __arraycount(exps); i++)
206		ATF_CHECK(scalbnf(x, exps[i]) == x);
207#endif
208}
209
210ATF_TC(scalbnf_inf_pos);
211ATF_TC_HEAD(scalbnf_inf_pos, tc)
212{
213	atf_tc_set_md_var(tc, "descr", "Test scalbnf(+Inf, n) == +Inf");
214}
215
216ATF_TC_BODY(scalbnf_inf_pos, tc)
217{
218#ifndef __vax__
219	const float x = 1.0L / 0.0L;
220	size_t i;
221
222	for (i = 0; i < __arraycount(exps); i++)
223		ATF_CHECK(scalbnf(x, exps[i]) == x);
224#endif
225}
226
227ATF_TC(scalbnf_ldexpf);
228ATF_TC_HEAD(scalbnf_ldexpf, tc)
229{
230	atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)");
231}
232
233ATF_TC_BODY(scalbnf_ldexpf, tc)
234{
235#ifndef __vax__
236#if FLT_RADIX == 2
237	const float x = 2.91288191221812821;
238	float y;
239	size_t i;
240
241	for (i = 0; i < __arraycount(exps); i++) {
242		y = scalbnf(x, exps[i]);
243		ATF_CHECK(y == ldexpf(x, exps[i]));
244	}
245#endif
246#endif
247}
248
249ATF_TC(scalbnf_zero_neg);
250ATF_TC_HEAD(scalbnf_zero_neg, tc)
251{
252	atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0");
253}
254
255ATF_TC_BODY(scalbnf_zero_neg, tc)
256{
257#ifndef __vax__
258	const float x = -0.0L;
259	float y;
260	size_t i;
261
262	ATF_REQUIRE(signbit(x) != 0);
263
264	for (i = 0; i < __arraycount(exps); i++) {
265		y = scalbnf(x, exps[i]);
266		ATF_CHECK(x == y);
267		ATF_CHECK(signbit(y) != 0);
268	}
269#endif
270}
271
272ATF_TC(scalbnf_zero_pos);
273ATF_TC_HEAD(scalbnf_zero_pos, tc)
274{
275	atf_tc_set_md_var(tc, "descr", "Test scalbnf(+0.0, n) == +0.0");
276}
277
278ATF_TC_BODY(scalbnf_zero_pos, tc)
279{
280#ifndef __vax__
281	const float x = 0.0L;
282	float y;
283	size_t i;
284
285	ATF_REQUIRE(signbit(x) == 0);
286
287	for (i = 0; i < __arraycount(exps); i++) {
288		y = scalbnf(x, exps[i]);
289		ATF_CHECK(x == y);
290		ATF_CHECK(signbit(y) == 0);
291	}
292#endif
293}
294
295/*
296 * scalbnl(3)
297 */
298ATF_TC(scalbnl_nan);
299ATF_TC_HEAD(scalbnl_nan, tc)
300{
301	atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN");
302}
303
304ATF_TC_BODY(scalbnl_nan, tc)
305{
306#ifndef __vax__
307#ifndef __HAVE_LONG_DOUBLE
308	atf_tc_skip("Requires long double support");
309#else
310	const long double x = 0.0L / 0.0L;
311	long double y;
312	size_t i;
313
314	if (isnan(x) == 0) {
315		atf_tc_expect_fail("PR lib/45362");
316		atf_tc_fail("(0.0L / 0.0L) != NaN");
317	}
318
319	for (i = 0; i < __arraycount(exps); i++) {
320		y = scalbnl(x, exps[i]);
321		ATF_CHECK(isnan(y) != 0);
322	}
323#endif
324#endif
325}
326
327ATF_TC(scalbnl_inf_neg);
328ATF_TC_HEAD(scalbnl_inf_neg, tc)
329{
330	atf_tc_set_md_var(tc, "descr", "Test scalbnl(-Inf, n) == -Inf");
331}
332
333ATF_TC_BODY(scalbnl_inf_neg, tc)
334{
335#ifndef __vax__
336#ifndef __HAVE_LONG_DOUBLE
337	atf_tc_skip("Requires long double support");
338#else
339	const long double x = -1.0L / 0.0L;
340	size_t i;
341
342	for (i = 0; i < __arraycount(exps); i++)
343		ATF_CHECK(scalbnl(x, exps[i]) == x);
344#endif
345#endif
346}
347
348ATF_TC(scalbnl_inf_pos);
349ATF_TC_HEAD(scalbnl_inf_pos, tc)
350{
351	atf_tc_set_md_var(tc, "descr", "Test scalbnl(+Inf, n) == +Inf");
352}
353
354ATF_TC_BODY(scalbnl_inf_pos, tc)
355{
356#ifndef __vax__
357#ifndef __HAVE_LONG_DOUBLE
358	atf_tc_skip("Requires long double support");
359#else
360	const long double x = 1.0L / 0.0L;
361	size_t i;
362
363	for (i = 0; i < __arraycount(exps); i++)
364		ATF_CHECK(scalbnl(x, exps[i]) == x);
365#endif
366#endif
367}
368
369ATF_TC(scalbnl_zero_neg);
370ATF_TC_HEAD(scalbnl_zero_neg, tc)
371{
372	atf_tc_set_md_var(tc, "descr", "Test scalbnl(-0.0, n) == -0.0");
373}
374
375ATF_TC_BODY(scalbnl_zero_neg, tc)
376{
377#ifndef __vax__
378#ifndef __HAVE_LONG_DOUBLE
379	atf_tc_skip("Requires long double support");
380#else
381	const long double x = -0.0L;
382	long double y;
383	size_t i;
384
385	ATF_REQUIRE(signbit(x) != 0);
386
387	for (i = 0; i < __arraycount(exps); i++) {
388		y = scalbnl(x, exps[i]);
389		ATF_CHECK(x == y);
390		ATF_CHECK(signbit(y) != 0);
391	}
392#endif
393#endif
394}
395
396ATF_TC(scalbnl_zero_pos);
397ATF_TC_HEAD(scalbnl_zero_pos, tc)
398{
399	atf_tc_set_md_var(tc, "descr", "Test scalbnl(+0.0, n) == +0.0");
400}
401
402ATF_TC_BODY(scalbnl_zero_pos, tc)
403{
404#ifndef __vax__
405#ifndef __HAVE_LONG_DOUBLE
406	atf_tc_skip("Requires long double support");
407#else
408	const long double x = 0.0L;
409	long double y;
410	size_t i;
411
412	ATF_REQUIRE(signbit(x) == 0);
413
414	for (i = 0; i < __arraycount(exps); i++) {
415		y = scalbnl(x, exps[i]);
416		ATF_CHECK(x == y);
417		ATF_CHECK(signbit(y) == 0);
418	}
419#endif
420#endif
421}
422
423ATF_TP_ADD_TCS(tp)
424{
425
426	ATF_TP_ADD_TC(tp, scalbn_nan);
427	ATF_TP_ADD_TC(tp, scalbn_inf_neg);
428	ATF_TP_ADD_TC(tp, scalbn_inf_pos);
429	ATF_TP_ADD_TC(tp, scalbn_ldexp);
430	ATF_TP_ADD_TC(tp, scalbn_zero_neg);
431	ATF_TP_ADD_TC(tp, scalbn_zero_pos);
432
433	ATF_TP_ADD_TC(tp, scalbnf_nan);
434	ATF_TP_ADD_TC(tp, scalbnf_inf_neg);
435	ATF_TP_ADD_TC(tp, scalbnf_inf_pos);
436	ATF_TP_ADD_TC(tp, scalbnf_ldexpf);
437	ATF_TP_ADD_TC(tp, scalbnf_zero_neg);
438	ATF_TP_ADD_TC(tp, scalbnf_zero_pos);
439
440	ATF_TP_ADD_TC(tp, scalbnl_nan);
441	ATF_TP_ADD_TC(tp, scalbnl_inf_neg);
442	ATF_TP_ADD_TC(tp, scalbnl_inf_pos);
443/*	ATF_TP_ADD_TC(tp, scalbnl_ldexp);	*/
444	ATF_TP_ADD_TC(tp, scalbnl_zero_neg);
445	ATF_TP_ADD_TC(tp, scalbnl_zero_pos);
446
447	return atf_no_error();
448}
449