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");