2 * Copyright (c) 2007 David Schultz <das@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Tests for csqrt{,f}()
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
40 #define N(i) (sizeof(i) / sizeof((i)[0]))
43 * This is a test hook that can point to csqrtl(), _csqrt(), or to _csqrtf().
44 * The latter two convert to float or double, respectively, and test csqrtf()
45 * and csqrt() with the same arguments.
47 long double complex (*t_csqrt)(long double complex);
49 static long double complex
50 _csqrtf(long double complex d)
53 return (csqrtf((float complex)d));
56 static long double complex
57 _csqrt(long double complex d)
60 return (csqrt((double complex)d));
63 #pragma STDC CX_LIMITED_RANGE off
66 * XXX gcc implements complex multiplication incorrectly. In
67 * particular, it implements it as if the CX_LIMITED_RANGE pragma
68 * were ON. Consequently, we need this function to form numbers
69 * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
72 static inline long double complex
73 cpackl(long double x, long double y)
75 long double complex z;
83 * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
84 * Fail an assertion if they differ.
87 assert_equal(long double complex d1, long double complex d2)
90 if (isnan(creall(d1))) {
91 assert(isnan(creall(d2)));
93 assert(creall(d1) == creall(d2));
94 assert(copysignl(1.0, creall(d1)) ==
95 copysignl(1.0, creall(d2)));
97 if (isnan(cimagl(d1))) {
98 assert(isnan(cimagl(d2)));
100 assert(cimagl(d1) == cimagl(d2));
101 assert(copysignl(1.0, cimagl(d1)) ==
102 copysignl(1.0, cimagl(d2)));
107 * Test csqrt for some finite arguments where the answer is exact.
108 * (We do not test if it produces correctly rounded answers when the
109 * result is inexact, nor do we check whether it throws spurious
115 static const double tests[] = {
116 /* csqrt(a + bI) = x + yI */
136 460766389075.0, 16762287900.0, 678910, 12345
139 * We also test some multiples of the above arguments. This
140 * array defines which multiples we use. Note that these have
141 * to be small enough to not cause overflow for float precision
142 * with all of the constants in the above table.
144 static const double mults[] = {
158 for (i = 0; i < N(tests); i += 4) {
159 for (j = 0; j < N(mults); j++) {
160 a = tests[i] * mults[j] * mults[j];
161 b = tests[i + 1] * mults[j] * mults[j];
162 x = tests[i + 2] * mults[j];
163 y = tests[i + 3] * mults[j];
164 assert(t_csqrt(cpackl(a, b)) == cpackl(x, y));
171 * Test the handling of +/- 0.
177 assert_equal(t_csqrt(cpackl(0.0, 0.0)), cpackl(0.0, 0.0));
178 assert_equal(t_csqrt(cpackl(-0.0, 0.0)), cpackl(0.0, 0.0));
179 assert_equal(t_csqrt(cpackl(0.0, -0.0)), cpackl(0.0, -0.0));
180 assert_equal(t_csqrt(cpackl(-0.0, -0.0)), cpackl(0.0, -0.0));
184 * Test the handling of infinities when the other argument is not NaN.
189 static const double vals[] = {
200 for (i = 0; i < N(vals); i++) {
201 if (isfinite(vals[i])) {
202 assert_equal(t_csqrt(cpackl(-INFINITY, vals[i])),
203 cpackl(0.0, copysignl(INFINITY, vals[i])));
204 assert_equal(t_csqrt(cpackl(INFINITY, vals[i])),
205 cpackl(INFINITY, copysignl(0.0, vals[i])));
207 assert_equal(t_csqrt(cpackl(vals[i], INFINITY)),
208 cpackl(INFINITY, INFINITY));
209 assert_equal(t_csqrt(cpackl(vals[i], -INFINITY)),
210 cpackl(INFINITY, -INFINITY));
215 * Test the handling of NaNs.
221 assert(creall(t_csqrt(cpackl(INFINITY, NAN))) == INFINITY);
222 assert(isnan(cimagl(t_csqrt(cpackl(INFINITY, NAN)))));
224 assert(isnan(creall(t_csqrt(cpackl(-INFINITY, NAN)))));
225 assert(isinf(cimagl(t_csqrt(cpackl(-INFINITY, NAN)))));
227 assert_equal(t_csqrt(cpackl(NAN, INFINITY)),
228 cpackl(INFINITY, INFINITY));
229 assert_equal(t_csqrt(cpackl(NAN, -INFINITY)),
230 cpackl(INFINITY, -INFINITY));
232 assert_equal(t_csqrt(cpackl(0.0, NAN)), cpackl(NAN, NAN));
233 assert_equal(t_csqrt(cpackl(-0.0, NAN)), cpackl(NAN, NAN));
234 assert_equal(t_csqrt(cpackl(42.0, NAN)), cpackl(NAN, NAN));
235 assert_equal(t_csqrt(cpackl(-42.0, NAN)), cpackl(NAN, NAN));
236 assert_equal(t_csqrt(cpackl(NAN, 0.0)), cpackl(NAN, NAN));
237 assert_equal(t_csqrt(cpackl(NAN, -0.0)), cpackl(NAN, NAN));
238 assert_equal(t_csqrt(cpackl(NAN, 42.0)), cpackl(NAN, NAN));
239 assert_equal(t_csqrt(cpackl(NAN, -42.0)), cpackl(NAN, NAN));
240 assert_equal(t_csqrt(cpackl(NAN, NAN)), cpackl(NAN, NAN));
244 * Test whether csqrt(a + bi) works for inputs that are large enough to
245 * cause overflow in hypot(a, b) + a. In this case we are using
246 * csqrt(115 + 252*I) == 14 + 9*I
247 * scaled up to near MAX_EXP.
250 test_overflow(int maxexp)
253 long double complex result;
255 a = ldexpl(115 * 0x1p-8, maxexp);
256 b = ldexpl(252 * 0x1p-8, maxexp);
257 result = t_csqrt(cpackl(a, b));
258 assert(creall(result) == ldexpl(14 * 0x1p-4, maxexp / 2));
259 assert(cimagl(result) == ldexpl(9 * 0x1p-4, maxexp / 2));
263 main(int argc, char *argv[])
272 printf("ok 1 - csqrt\n");
275 printf("ok 2 - csqrt\n");
278 printf("ok 3 - csqrt\n");
281 printf("ok 4 - csqrt\n");
283 test_overflow(DBL_MAX_EXP);
284 printf("ok 5 - csqrt\n");
286 /* Now test csqrtf() */
290 printf("ok 6 - csqrt\n");
293 printf("ok 7 - csqrt\n");
296 printf("ok 8 - csqrt\n");
299 printf("ok 9 - csqrt\n");
301 test_overflow(FLT_MAX_EXP);
302 printf("ok 10 - csqrt\n");
304 /* Now test csqrtl() */
308 printf("ok 11 - csqrt\n");
311 printf("ok 12 - csqrt\n");
314 printf("ok 13 - csqrt\n");
317 printf("ok 14 - csqrt\n");
319 test_overflow(LDBL_MAX_EXP);
320 printf("ok 15 - csqrt\n");