t_ldexp.c revision 1.8 1 /* $NetBSD: t_ldexp.c,v 1.8 2011/09/16 04:54:46 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_ldexp.c,v 1.8 2011/09/16 04:54:46 jruoho Exp $");
33
34 #include <math.h>
35 #include <limits.h>
36
37 #include <atf-c.h>
38
39 static const int exps[] = { 0, 1, -1, 100, -100 };
40
41 /*
42 * ldexp(3)
43 */
44 ATF_TC(ldexp_exp2);
45 ATF_TC_HEAD(ldexp_exp2, tc)
46 {
47 atf_tc_set_md_var(tc, "descr", "Test ldexp(x, n) == x * exp2(n)");
48 }
49
50 ATF_TC_BODY(ldexp_exp2, tc)
51 {
52 #ifndef __vax__
53 const double n[] = { 1, 2, 3, 25, 50, 100, 123, 321, 500 };
54 const double eps = 1.0e-40;
55 const double x = 12.0;
56 double y;
57 size_t i;
58
59 for (i = 0; i < __arraycount(n); i++) {
60
61 y = ldexp(x, n[i]);
62
63 if (fabs(y - (x * exp2(n[i]))) > eps) {
64 atf_tc_fail_nonfatal("ldexp(%0.01f, %0.01f) "
65 "!= %0.01f * exp2(%0.01f)", x, n[i], x, n[i]);
66 }
67 }
68 #endif
69 }
70
71 ATF_TC(ldexp_nan);
72 ATF_TC_HEAD(ldexp_nan, tc)
73 {
74 atf_tc_set_md_var(tc, "descr", "Test ldexp(NaN) == NaN");
75 }
76
77 ATF_TC_BODY(ldexp_nan, tc)
78 {
79 #ifndef __vax__
80 const double x = 0.0L / 0.0L;
81 double y;
82 size_t i;
83
84 ATF_REQUIRE(isnan(x) != 0);
85
86 for (i = 0; i < __arraycount(exps); i++) {
87 y = ldexp(x, exps[i]);
88 ATF_CHECK(isnan(y) != 0);
89 }
90 #endif
91 }
92
93 ATF_TC(ldexp_inf_neg);
94 ATF_TC_HEAD(ldexp_inf_neg, tc)
95 {
96 atf_tc_set_md_var(tc, "descr", "Test ldexp(-Inf) == -Inf");
97 }
98
99 ATF_TC_BODY(ldexp_inf_neg, tc)
100 {
101 #ifndef __vax__
102 const double x = -1.0L / 0.0L;
103 size_t i;
104
105 for (i = 0; i < __arraycount(exps); i++)
106 ATF_CHECK(ldexp(x, exps[i]) == x);
107 #endif
108 }
109
110 ATF_TC(ldexp_inf_pos);
111 ATF_TC_HEAD(ldexp_inf_pos, tc)
112 {
113 atf_tc_set_md_var(tc, "descr", "Test ldexp(+Inf) == +Inf");
114 }
115
116 ATF_TC_BODY(ldexp_inf_pos, tc)
117 {
118 #ifndef __vax__
119 const double x = 1.0L / 0.0L;
120 size_t i;
121
122 for (i = 0; i < __arraycount(exps); i++)
123 ATF_CHECK(ldexp(x, exps[i]) == x);
124 #endif
125 }
126
127 ATF_TC(ldexp_zero_neg);
128 ATF_TC_HEAD(ldexp_zero_neg, tc)
129 {
130 atf_tc_set_md_var(tc, "descr", "Test ldexp(-0.0) == -0.0");
131 }
132
133 ATF_TC_BODY(ldexp_zero_neg, tc)
134 {
135 #ifndef __vax__
136 const double x = -0.0L;
137 double y;
138 size_t i;
139
140 ATF_REQUIRE(signbit(x) != 0);
141
142 for (i = 0; i < __arraycount(exps); i++) {
143 y = ldexp(x, exps[i]);
144 ATF_CHECK(x == y);
145 ATF_CHECK(signbit(y) != 0);
146 }
147 #endif
148 }
149
150 ATF_TC(ldexp_zero_pos);
151 ATF_TC_HEAD(ldexp_zero_pos, tc)
152 {
153 atf_tc_set_md_var(tc, "descr", "Test ldexp(+0.0) == +0.0");
154 }
155
156 ATF_TC_BODY(ldexp_zero_pos, tc)
157 {
158 #ifndef __vax__
159 const double x = 0.0L;
160 double y;
161 size_t i;
162
163 ATF_REQUIRE(signbit(x) == 0);
164
165 for (i = 0; i < __arraycount(exps); i++) {
166 y = ldexp(x, exps[i]);
167 ATF_CHECK(x == y);
168 ATF_CHECK(signbit(y) == 0);
169 }
170 #endif
171 }
172
173 /*
174 * ldexpf(3)
175 */
176
177 ATF_TC(ldexpf_exp2f);
178 ATF_TC_HEAD(ldexpf_exp2f, tc)
179 {
180 atf_tc_set_md_var(tc, "descr", "Test ldexpf(x, n) == x * exp2f(n)");
181 }
182
183 ATF_TC_BODY(ldexpf_exp2f, tc)
184 {
185 #ifndef __vax__
186 const float n[] = { 1, 2, 3, 25, 50, 100, 123, 321, 500 };
187 const float eps = 1.0e-9;
188 const float x = 12;
189 float y;
190 size_t i;
191
192 for (i = 0; i < __arraycount(n); i++) {
193
194 y = ldexpf(x, n[i]);
195
196 if (fabsf(y - (x * exp2f(n[i]))) > eps) {
197 atf_tc_fail_nonfatal("ldexpf(%0.01f, %0.01f) "
198 "!= %0.01f * exp2f(%0.01f)", x, n[i], x, n[i]);
199 }
200 }
201 #endif
202 }
203
204 ATF_TC(ldexpf_nan);
205 ATF_TC_HEAD(ldexpf_nan, tc)
206 {
207 atf_tc_set_md_var(tc, "descr", "Test ldexpf(NaN) == NaN");
208 }
209
210 ATF_TC_BODY(ldexpf_nan, tc)
211 {
212 #ifndef __vax__
213 const float x = 0.0L / 0.0L;
214 float y;
215 size_t i;
216
217 ATF_REQUIRE(isnan(x) != 0);
218
219 for (i = 0; i < __arraycount(exps); i++) {
220 y = ldexpf(x, exps[i]);
221 ATF_CHECK(isnan(y) != 0);
222 }
223 #endif
224 }
225
226 ATF_TC(ldexpf_inf_neg);
227 ATF_TC_HEAD(ldexpf_inf_neg, tc)
228 {
229 atf_tc_set_md_var(tc, "descr", "Test ldexpf(-Inf) == -Inf");
230 }
231
232 ATF_TC_BODY(ldexpf_inf_neg, tc)
233 {
234 #ifndef __vax__
235 const float x = -1.0L / 0.0L;
236 size_t i;
237
238 for (i = 0; i < __arraycount(exps); i++)
239 ATF_CHECK(ldexpf(x, exps[i]) == x);
240 #endif
241 }
242
243 ATF_TC(ldexpf_inf_pos);
244 ATF_TC_HEAD(ldexpf_inf_pos, tc)
245 {
246 atf_tc_set_md_var(tc, "descr", "Test ldexpf(+Inf) == +Inf");
247 }
248
249 ATF_TC_BODY(ldexpf_inf_pos, tc)
250 {
251 #ifndef __vax__
252 const float x = 1.0L / 0.0L;
253 size_t i;
254
255 for (i = 0; i < __arraycount(exps); i++)
256 ATF_CHECK(ldexpf(x, exps[i]) == x);
257 #endif
258 }
259
260 ATF_TC(ldexpf_zero_neg);
261 ATF_TC_HEAD(ldexpf_zero_neg, tc)
262 {
263 atf_tc_set_md_var(tc, "descr", "Test ldexpf(-0.0) == -0.0");
264 }
265
266 ATF_TC_BODY(ldexpf_zero_neg, tc)
267 {
268 #ifndef __vax__
269 const float x = -0.0L;
270 float y;
271 size_t i;
272
273 ATF_REQUIRE(signbit(x) != 0);
274
275 for (i = 0; i < __arraycount(exps); i++) {
276 y = ldexpf(x, exps[i]);
277 ATF_CHECK(x == y);
278 ATF_CHECK(signbit(y) != 0);
279 }
280 #endif
281 }
282
283 ATF_TC(ldexpf_zero_pos);
284 ATF_TC_HEAD(ldexpf_zero_pos, tc)
285 {
286 atf_tc_set_md_var(tc, "descr", "Test ldexpf(+0.0) == +0.0");
287 }
288
289 ATF_TC_BODY(ldexpf_zero_pos, tc)
290 {
291 #ifndef __vax__
292 const float x = 0.0L;
293 float y;
294 size_t i;
295
296 ATF_REQUIRE(signbit(x) == 0);
297
298 for (i = 0; i < __arraycount(exps); i++) {
299 y = ldexpf(x, exps[i]);
300 ATF_CHECK(x == y);
301 ATF_CHECK(signbit(y) == 0);
302 }
303 #endif
304 }
305
306 ATF_TP_ADD_TCS(tp)
307 {
308
309 ATF_TP_ADD_TC(tp, ldexp_exp2);
310 ATF_TP_ADD_TC(tp, ldexp_nan);
311 ATF_TP_ADD_TC(tp, ldexp_inf_neg);
312 ATF_TP_ADD_TC(tp, ldexp_inf_pos);
313 ATF_TP_ADD_TC(tp, ldexp_zero_neg);
314 ATF_TP_ADD_TC(tp, ldexp_zero_pos);
315
316 ATF_TP_ADD_TC(tp, ldexpf_exp2f);
317 ATF_TP_ADD_TC(tp, ldexpf_nan);
318 ATF_TP_ADD_TC(tp, ldexpf_inf_neg);
319 ATF_TP_ADD_TC(tp, ldexpf_inf_pos);
320 ATF_TP_ADD_TC(tp, ldexpf_zero_neg);
321 ATF_TP_ADD_TC(tp, ldexpf_zero_pos);
322
323 return atf_no_error();
324 }
325