xref: /netbsd-src/tests/lib/libm/t_sqrt.c (revision 29ebc6818ee8e63212fdcad6d1dd985b3adf5267)
1 /* $NetBSD: t_sqrt.c,v 1.6 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_sqrt.c,v 1.6 2014/03/03 10:39:08 martin Exp $");
33 
34 #include <atf-c.h>
35 #include <math.h>
36 #include <float.h>
37 #include <stdio.h>
38 
39 /*
40  * sqrt(3)
41  */
42 ATF_TC(sqrt_nan);
43 ATF_TC_HEAD(sqrt_nan, tc)
44 {
45 	atf_tc_set_md_var(tc, "descr", "Test sqrt(NaN) == NaN");
46 }
47 
48 ATF_TC_BODY(sqrt_nan, tc)
49 {
50 	const double x = 0.0L / 0.0L;
51 
52 	ATF_CHECK(isnan(x) != 0);
53 	ATF_CHECK(isnan(sqrt(x)) != 0);
54 }
55 
56 ATF_TC(sqrt_pow);
57 ATF_TC_HEAD(sqrt_pow, tc)
58 {
59 	atf_tc_set_md_var(tc, "descr", "Test sqrt(3) vs. pow(3)");
60 }
61 
62 ATF_TC_BODY(sqrt_pow, tc)
63 {
64 	const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
65 	const double eps = 1.0e-40;
66 	double y, z;
67 	size_t i;
68 
69 	for (i = 0; i < __arraycount(x); i++) {
70 
71 		y = sqrt(x[i]);
72 		z = pow(x[i], 1.0 / 2.0);
73 
74 		if (fabs(y - z) > eps)
75 			atf_tc_fail_nonfatal("sqrt(%0.03f) != "
76 			    "pow(%0.03f, 1/2)\n", x[i], x[i]);
77 	}
78 }
79 
80 ATF_TC(sqrt_inf_neg);
81 ATF_TC_HEAD(sqrt_inf_neg, tc)
82 {
83 	atf_tc_set_md_var(tc, "descr", "Test sqrt(-Inf) == NaN");
84 }
85 
86 ATF_TC_BODY(sqrt_inf_neg, tc)
87 {
88 	const double x = -1.0L / 0.0L;
89 	double y = sqrt(x);
90 
91 	ATF_CHECK(isnan(y) != 0);
92 }
93 
94 ATF_TC(sqrt_inf_pos);
95 ATF_TC_HEAD(sqrt_inf_pos, tc)
96 {
97 	atf_tc_set_md_var(tc, "descr", "Test sqrt(+Inf) == +Inf");
98 }
99 
100 ATF_TC_BODY(sqrt_inf_pos, tc)
101 {
102 	const double x = 1.0L / 0.0L;
103 	double y = sqrt(x);
104 
105 	ATF_CHECK(isinf(y) != 0);
106 	ATF_CHECK(signbit(y) == 0);
107 }
108 
109 ATF_TC(sqrt_zero_neg);
110 ATF_TC_HEAD(sqrt_zero_neg, tc)
111 {
112 	atf_tc_set_md_var(tc, "descr", "Test sqrt(-0.0) == -0.0");
113 }
114 
115 ATF_TC_BODY(sqrt_zero_neg, tc)
116 {
117 	const double x = -0.0L;
118 	double y = sqrt(x);
119 
120 	if (fabs(y) > 0.0 || signbit(y) == 0)
121 		atf_tc_fail_nonfatal("sqrt(-0.0) != -0.0");
122 }
123 
124 ATF_TC(sqrt_zero_pos);
125 ATF_TC_HEAD(sqrt_zero_pos, tc)
126 {
127 	atf_tc_set_md_var(tc, "descr", "Test sqrt(+0.0) == +0.0");
128 }
129 
130 ATF_TC_BODY(sqrt_zero_pos, tc)
131 {
132 	const double x = 0.0L;
133 	double y = sqrt(x);
134 
135 	if (fabs(y) > 0.0 || signbit(y) != 0)
136 		atf_tc_fail_nonfatal("sqrt(+0.0) != +0.0");
137 }
138 
139 /*
140  * sqrtf(3)
141  */
142 ATF_TC(sqrtf_nan);
143 ATF_TC_HEAD(sqrtf_nan, tc)
144 {
145 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(NaN) == NaN");
146 }
147 
148 ATF_TC_BODY(sqrtf_nan, tc)
149 {
150 	const float x = 0.0L / 0.0L;
151 
152 	ATF_CHECK(isnan(x) != 0);
153 	ATF_CHECK(isnan(sqrtf(x)) != 0);
154 }
155 
156 ATF_TC(sqrtf_powf);
157 ATF_TC_HEAD(sqrtf_powf, tc)
158 {
159 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(3) vs. powf(3)");
160 }
161 
162 ATF_TC_BODY(sqrtf_powf, tc)
163 {
164 	const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
165 	const float eps = 1.0e-30;
166 	volatile float y, z;
167 	size_t i;
168 
169 	for (i = 0; i < __arraycount(x); i++) {
170 
171 		y = sqrtf(x[i]);
172 		z = powf(x[i], 1.0 / 2.0);
173 
174 		if (fabsf(y - z) > eps)
175 			atf_tc_fail_nonfatal("sqrtf(%0.03f) != "
176 			    "powf(%0.03f, 1/2)\n", x[i], x[i]);
177 	}
178 }
179 
180 ATF_TC(sqrtf_inf_neg);
181 ATF_TC_HEAD(sqrtf_inf_neg, tc)
182 {
183 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(-Inf) == NaN");
184 }
185 
186 ATF_TC_BODY(sqrtf_inf_neg, tc)
187 {
188 	const float x = -1.0L / 0.0L;
189 	float y = sqrtf(x);
190 
191 	ATF_CHECK(isnan(y) != 0);
192 }
193 
194 ATF_TC(sqrtf_inf_pos);
195 ATF_TC_HEAD(sqrtf_inf_pos, tc)
196 {
197 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(+Inf) == +Inf");
198 }
199 
200 ATF_TC_BODY(sqrtf_inf_pos, tc)
201 {
202 	const float x = 1.0L / 0.0L;
203 	float y = sqrtf(x);
204 
205 	ATF_CHECK(isinf(y) != 0);
206 	ATF_CHECK(signbit(y) == 0);
207 }
208 
209 ATF_TC(sqrtf_zero_neg);
210 ATF_TC_HEAD(sqrtf_zero_neg, tc)
211 {
212 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(-0.0) == -0.0");
213 }
214 
215 ATF_TC_BODY(sqrtf_zero_neg, tc)
216 {
217 	const float x = -0.0L;
218 	float y = sqrtf(x);
219 
220 	if (fabsf(y) > 0.0 || signbit(y) == 0)
221 		atf_tc_fail_nonfatal("sqrtf(-0.0) != -0.0");
222 }
223 
224 ATF_TC(sqrtf_zero_pos);
225 ATF_TC_HEAD(sqrtf_zero_pos, tc)
226 {
227 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(+0.0) == +0.0");
228 }
229 
230 ATF_TC_BODY(sqrtf_zero_pos, tc)
231 {
232 	const float x = 0.0L;
233 	float y = sqrtf(x);
234 
235 	if (fabsf(y) > 0.0 || signbit(y) != 0)
236 		atf_tc_fail_nonfatal("sqrtf(+0.0) != +0.0");
237 }
238 
239 /*
240  * sqrtl(3)
241  */
242 ATF_TC(sqrtl_nan);
243 ATF_TC_HEAD(sqrtl_nan, tc)
244 {
245 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(NaN) == NaN");
246 }
247 
248 ATF_TC_BODY(sqrtl_nan, tc)
249 {
250 	const long double x = 0.0L / 0.0L;
251 
252 	ATF_CHECK(isnan(x) != 0);
253 	ATF_CHECK(isnan(sqrtl(x)) != 0);
254 }
255 
256 ATF_TC(sqrtl_powl);
257 ATF_TC_HEAD(sqrtl_powl, tc)
258 {
259 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(3) vs. powl(3)");
260 }
261 
262 ATF_TC_BODY(sqrtl_powl, tc)
263 {
264 	const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
265 	const long double eps = 5.0*DBL_EPSILON; /* XXX powl == pow for now */
266 	volatile long double y, z;
267 	size_t i;
268 
269 	for (i = 0; i < __arraycount(x); i++) {
270 
271 		y = sqrtl(x[i]);
272 		z = powl(x[i], 1.0 / 2.0);
273 
274 		if (fabsl(y - z) > eps)
275 			atf_tc_fail_nonfatal("sqrtl(%0.03Lf) != "
276 			    "powl(%0.03Lf, 1/2)\n", x[i], x[i]);
277 	}
278 }
279 
280 ATF_TC(sqrtl_inf_neg);
281 ATF_TC_HEAD(sqrtl_inf_neg, tc)
282 {
283 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(-Inf) == NaN");
284 }
285 
286 ATF_TC_BODY(sqrtl_inf_neg, tc)
287 {
288 	const long double x = -1.0L / 0.0L;
289 	long double y = sqrtl(x);
290 
291 	ATF_CHECK(isnan(y) != 0);
292 }
293 
294 ATF_TC(sqrtl_inf_pos);
295 ATF_TC_HEAD(sqrtl_inf_pos, tc)
296 {
297 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(+Inf) == +Inf");
298 }
299 
300 ATF_TC_BODY(sqrtl_inf_pos, tc)
301 {
302 	const long double x = 1.0L / 0.0L;
303 	long double y = sqrtl(x);
304 
305 	ATF_CHECK(isinf(y) != 0);
306 	ATF_CHECK(signbit(y) == 0);
307 }
308 
309 ATF_TC(sqrtl_zero_neg);
310 ATF_TC_HEAD(sqrtl_zero_neg, tc)
311 {
312 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(-0.0) == -0.0");
313 }
314 
315 ATF_TC_BODY(sqrtl_zero_neg, tc)
316 {
317 	const long double x = -0.0L;
318 	long double y = sqrtl(x);
319 
320 	if (fabsl(y) > 0.0 || signbit(y) == 0)
321 		atf_tc_fail_nonfatal("sqrtl(-0.0) != -0.0");
322 }
323 
324 ATF_TC(sqrtl_zero_pos);
325 ATF_TC_HEAD(sqrtl_zero_pos, tc)
326 {
327 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(+0.0) == +0.0");
328 }
329 
330 ATF_TC_BODY(sqrtl_zero_pos, tc)
331 {
332 	const long double x = 0.0L;
333 	long double y = sqrtl(x);
334 
335 	if (fabsl(y) > 0.0 || signbit(y) != 0)
336 		atf_tc_fail_nonfatal("sqrtl(+0.0) != +0.0");
337 }
338 
339 ATF_TP_ADD_TCS(tp)
340 {
341 
342 	ATF_TP_ADD_TC(tp, sqrt_nan);
343 	ATF_TP_ADD_TC(tp, sqrt_pow);
344 	ATF_TP_ADD_TC(tp, sqrt_inf_neg);
345 	ATF_TP_ADD_TC(tp, sqrt_inf_pos);
346 	ATF_TP_ADD_TC(tp, sqrt_zero_neg);
347 	ATF_TP_ADD_TC(tp, sqrt_zero_pos);
348 
349 	ATF_TP_ADD_TC(tp, sqrtf_nan);
350 	ATF_TP_ADD_TC(tp, sqrtf_powf);
351 	ATF_TP_ADD_TC(tp, sqrtf_inf_neg);
352 	ATF_TP_ADD_TC(tp, sqrtf_inf_pos);
353 	ATF_TP_ADD_TC(tp, sqrtf_zero_neg);
354 	ATF_TP_ADD_TC(tp, sqrtf_zero_pos);
355 
356 	ATF_TP_ADD_TC(tp, sqrtl_nan);
357 	ATF_TP_ADD_TC(tp, sqrtl_powl);
358 	ATF_TP_ADD_TC(tp, sqrtl_inf_neg);
359 	ATF_TP_ADD_TC(tp, sqrtl_inf_pos);
360 	ATF_TP_ADD_TC(tp, sqrtl_zero_neg);
361 	ATF_TP_ADD_TC(tp, sqrtl_zero_pos);
362 
363 	return atf_no_error();
364 }
365