csqrt_test.c revision 271296
1174619Sdas/*- 2174619Sdas * Copyright (c) 2007 David Schultz <das@FreeBSD.org> 3174619Sdas * All rights reserved. 4174619Sdas * 5174619Sdas * Redistribution and use in source and binary forms, with or without 6174619Sdas * modification, are permitted provided that the following conditions 7174619Sdas * are met: 8174619Sdas * 1. Redistributions of source code must retain the above copyright 9174619Sdas * notice, this list of conditions and the following disclaimer. 10174619Sdas * 2. Redistributions in binary form must reproduce the above copyright 11174619Sdas * notice, this list of conditions and the following disclaimer in the 12174619Sdas * documentation and/or other materials provided with the distribution. 13174619Sdas * 14174619Sdas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15174619Sdas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16174619Sdas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17174619Sdas * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18174619Sdas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19174619Sdas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20174619Sdas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21174619Sdas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22174619Sdas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23174619Sdas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24174619Sdas * SUCH DAMAGE. 25174619Sdas */ 26174619Sdas 27174619Sdas/* 28174619Sdas * Tests for csqrt{,f}() 29174619Sdas */ 30174619Sdas 31174619Sdas#include <sys/cdefs.h> 32174619Sdas__FBSDID("$FreeBSD: head/tools/regression/lib/msun/test-csqrt.c 271296 2014-09-09 02:58:58Z ngie $"); 33174619Sdas 34174619Sdas#include <assert.h> 35174619Sdas#include <complex.h> 36174619Sdas#include <float.h> 37174619Sdas#include <math.h> 38174619Sdas#include <stdio.h> 39174619Sdas 40251241Sdas#include "test-utils.h" 41251241Sdas 42174619Sdas#define N(i) (sizeof(i) / sizeof((i)[0])) 43174619Sdas 44174619Sdas/* 45177763Sdas * This is a test hook that can point to csqrtl(), _csqrt(), or to _csqrtf(). 46177763Sdas * The latter two convert to float or double, respectively, and test csqrtf() 47177763Sdas * and csqrt() with the same arguments. 48174619Sdas */ 49177763Sdaslong double complex (*t_csqrt)(long double complex); 50174619Sdas 51177763Sdasstatic long double complex 52177763Sdas_csqrtf(long double complex d) 53174619Sdas{ 54174619Sdas 55174619Sdas return (csqrtf((float complex)d)); 56174619Sdas} 57174619Sdas 58177763Sdasstatic long double complex 59177763Sdas_csqrt(long double complex d) 60177763Sdas{ 61177763Sdas 62177763Sdas return (csqrt((double complex)d)); 63177763Sdas} 64177763Sdas 65271296Sngie#pragma STDC CX_LIMITED_RANGE OFF 66174619Sdas 67174619Sdas/* 68174619Sdas * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0. 69174619Sdas * Fail an assertion if they differ. 70174619Sdas */ 71174619Sdasstatic void 72177763Sdasassert_equal(long double complex d1, long double complex d2) 73174619Sdas{ 74174619Sdas 75251241Sdas assert(cfpequal(d1, d2)); 76174619Sdas} 77174619Sdas 78174619Sdas/* 79174619Sdas * Test csqrt for some finite arguments where the answer is exact. 80174619Sdas * (We do not test if it produces correctly rounded answers when the 81174619Sdas * result is inexact, nor do we check whether it throws spurious 82174619Sdas * exceptions.) 83174619Sdas */ 84174619Sdasstatic void 85174619Sdastest_finite() 86174619Sdas{ 87174619Sdas static const double tests[] = { 88174619Sdas /* csqrt(a + bI) = x + yI */ 89174619Sdas /* a b x y */ 90174619Sdas 0, 8, 2, 2, 91174619Sdas 0, -8, 2, -2, 92174619Sdas 4, 0, 2, 0, 93174619Sdas -4, 0, 0, 2, 94174619Sdas 3, 4, 2, 1, 95174619Sdas 3, -4, 2, -1, 96174619Sdas -3, 4, 1, 2, 97174619Sdas -3, -4, 1, -2, 98174619Sdas 5, 12, 3, 2, 99174619Sdas 7, 24, 4, 3, 100174619Sdas 9, 40, 5, 4, 101174619Sdas 11, 60, 6, 5, 102174619Sdas 13, 84, 7, 6, 103174619Sdas 33, 56, 7, 4, 104174619Sdas 39, 80, 8, 5, 105174619Sdas 65, 72, 9, 4, 106174619Sdas 987, 9916, 74, 67, 107174619Sdas 5289, 6640, 83, 40, 108174619Sdas 460766389075.0, 16762287900.0, 678910, 12345 109174619Sdas }; 110174619Sdas /* 111174619Sdas * We also test some multiples of the above arguments. This 112174619Sdas * array defines which multiples we use. Note that these have 113174619Sdas * to be small enough to not cause overflow for float precision 114174619Sdas * with all of the constants in the above table. 115174619Sdas */ 116174619Sdas static const double mults[] = { 117174619Sdas 1, 118174619Sdas 2, 119174619Sdas 3, 120174619Sdas 13, 121174619Sdas 16, 122174619Sdas 0x1.p30, 123174619Sdas 0x1.p-30, 124174619Sdas }; 125174619Sdas 126174619Sdas double a, b; 127174619Sdas double x, y; 128174619Sdas int i, j; 129174619Sdas 130174619Sdas for (i = 0; i < N(tests); i += 4) { 131174619Sdas for (j = 0; j < N(mults); j++) { 132174619Sdas a = tests[i] * mults[j] * mults[j]; 133174619Sdas b = tests[i + 1] * mults[j] * mults[j]; 134174619Sdas x = tests[i + 2] * mults[j]; 135174619Sdas y = tests[i + 3] * mults[j]; 136251241Sdas assert(t_csqrt(CMPLXL(a, b)) == CMPLXL(x, y)); 137174619Sdas } 138174619Sdas } 139174619Sdas 140174619Sdas} 141174619Sdas 142174619Sdas/* 143174619Sdas * Test the handling of +/- 0. 144174619Sdas */ 145174619Sdasstatic void 146174619Sdastest_zeros() 147174619Sdas{ 148174619Sdas 149251241Sdas assert_equal(t_csqrt(CMPLXL(0.0, 0.0)), CMPLXL(0.0, 0.0)); 150251241Sdas assert_equal(t_csqrt(CMPLXL(-0.0, 0.0)), CMPLXL(0.0, 0.0)); 151251241Sdas assert_equal(t_csqrt(CMPLXL(0.0, -0.0)), CMPLXL(0.0, -0.0)); 152251241Sdas assert_equal(t_csqrt(CMPLXL(-0.0, -0.0)), CMPLXL(0.0, -0.0)); 153174619Sdas} 154174619Sdas 155174619Sdas/* 156174619Sdas * Test the handling of infinities when the other argument is not NaN. 157174619Sdas */ 158174619Sdasstatic void 159174619Sdastest_infinities() 160174619Sdas{ 161174619Sdas static const double vals[] = { 162174619Sdas 0.0, 163174619Sdas -0.0, 164174619Sdas 42.0, 165174619Sdas -42.0, 166174619Sdas INFINITY, 167174619Sdas -INFINITY, 168174619Sdas }; 169174619Sdas 170174619Sdas int i; 171174619Sdas 172174619Sdas for (i = 0; i < N(vals); i++) { 173174619Sdas if (isfinite(vals[i])) { 174251241Sdas assert_equal(t_csqrt(CMPLXL(-INFINITY, vals[i])), 175251241Sdas CMPLXL(0.0, copysignl(INFINITY, vals[i]))); 176251241Sdas assert_equal(t_csqrt(CMPLXL(INFINITY, vals[i])), 177251241Sdas CMPLXL(INFINITY, copysignl(0.0, vals[i]))); 178174619Sdas } 179251241Sdas assert_equal(t_csqrt(CMPLXL(vals[i], INFINITY)), 180251241Sdas CMPLXL(INFINITY, INFINITY)); 181251241Sdas assert_equal(t_csqrt(CMPLXL(vals[i], -INFINITY)), 182251241Sdas CMPLXL(INFINITY, -INFINITY)); 183174619Sdas } 184174619Sdas} 185174619Sdas 186174619Sdas/* 187174619Sdas * Test the handling of NaNs. 188174619Sdas */ 189174619Sdasstatic void 190174619Sdastest_nans() 191174619Sdas{ 192174619Sdas 193251241Sdas assert(creall(t_csqrt(CMPLXL(INFINITY, NAN))) == INFINITY); 194251241Sdas assert(isnan(cimagl(t_csqrt(CMPLXL(INFINITY, NAN))))); 195174619Sdas 196251241Sdas assert(isnan(creall(t_csqrt(CMPLXL(-INFINITY, NAN))))); 197251241Sdas assert(isinf(cimagl(t_csqrt(CMPLXL(-INFINITY, NAN))))); 198174619Sdas 199251241Sdas assert_equal(t_csqrt(CMPLXL(NAN, INFINITY)), 200251241Sdas CMPLXL(INFINITY, INFINITY)); 201251241Sdas assert_equal(t_csqrt(CMPLXL(NAN, -INFINITY)), 202251241Sdas CMPLXL(INFINITY, -INFINITY)); 203174619Sdas 204251241Sdas assert_equal(t_csqrt(CMPLXL(0.0, NAN)), CMPLXL(NAN, NAN)); 205251241Sdas assert_equal(t_csqrt(CMPLXL(-0.0, NAN)), CMPLXL(NAN, NAN)); 206251241Sdas assert_equal(t_csqrt(CMPLXL(42.0, NAN)), CMPLXL(NAN, NAN)); 207251241Sdas assert_equal(t_csqrt(CMPLXL(-42.0, NAN)), CMPLXL(NAN, NAN)); 208251241Sdas assert_equal(t_csqrt(CMPLXL(NAN, 0.0)), CMPLXL(NAN, NAN)); 209251241Sdas assert_equal(t_csqrt(CMPLXL(NAN, -0.0)), CMPLXL(NAN, NAN)); 210251241Sdas assert_equal(t_csqrt(CMPLXL(NAN, 42.0)), CMPLXL(NAN, NAN)); 211251241Sdas assert_equal(t_csqrt(CMPLXL(NAN, -42.0)), CMPLXL(NAN, NAN)); 212251241Sdas assert_equal(t_csqrt(CMPLXL(NAN, NAN)), CMPLXL(NAN, NAN)); 213174619Sdas} 214174619Sdas 215174619Sdas/* 216174619Sdas * Test whether csqrt(a + bi) works for inputs that are large enough to 217174619Sdas * cause overflow in hypot(a, b) + a. In this case we are using 218174619Sdas * csqrt(115 + 252*I) == 14 + 9*I 219174619Sdas * scaled up to near MAX_EXP. 220174619Sdas */ 221174619Sdasstatic void 222174619Sdastest_overflow(int maxexp) 223174619Sdas{ 224177763Sdas long double a, b; 225177763Sdas long double complex result; 226174619Sdas 227177763Sdas a = ldexpl(115 * 0x1p-8, maxexp); 228177763Sdas b = ldexpl(252 * 0x1p-8, maxexp); 229251241Sdas result = t_csqrt(CMPLXL(a, b)); 230177763Sdas assert(creall(result) == ldexpl(14 * 0x1p-4, maxexp / 2)); 231177763Sdas assert(cimagl(result) == ldexpl(9 * 0x1p-4, maxexp / 2)); 232174619Sdas} 233174619Sdas 234174619Sdasint 235174619Sdasmain(int argc, char *argv[]) 236174619Sdas{ 237174619Sdas 238177763Sdas printf("1..15\n"); 239174619Sdas 240174619Sdas /* Test csqrt() */ 241177763Sdas t_csqrt = _csqrt; 242174619Sdas 243174619Sdas test_finite(); 244174619Sdas printf("ok 1 - csqrt\n"); 245174619Sdas 246174619Sdas test_zeros(); 247174619Sdas printf("ok 2 - csqrt\n"); 248174619Sdas 249174619Sdas test_infinities(); 250174619Sdas printf("ok 3 - csqrt\n"); 251174619Sdas 252174619Sdas test_nans(); 253174619Sdas printf("ok 4 - csqrt\n"); 254174619Sdas 255174619Sdas test_overflow(DBL_MAX_EXP); 256174619Sdas printf("ok 5 - csqrt\n"); 257174619Sdas 258174619Sdas /* Now test csqrtf() */ 259174619Sdas t_csqrt = _csqrtf; 260174619Sdas 261174619Sdas test_finite(); 262174619Sdas printf("ok 6 - csqrt\n"); 263174619Sdas 264174619Sdas test_zeros(); 265174619Sdas printf("ok 7 - csqrt\n"); 266174619Sdas 267174619Sdas test_infinities(); 268174619Sdas printf("ok 8 - csqrt\n"); 269174619Sdas 270174619Sdas test_nans(); 271174619Sdas printf("ok 9 - csqrt\n"); 272174619Sdas 273174619Sdas test_overflow(FLT_MAX_EXP); 274174619Sdas printf("ok 10 - csqrt\n"); 275174619Sdas 276177763Sdas /* Now test csqrtl() */ 277177763Sdas t_csqrt = csqrtl; 278177763Sdas 279177763Sdas test_finite(); 280177763Sdas printf("ok 11 - csqrt\n"); 281177763Sdas 282177763Sdas test_zeros(); 283177763Sdas printf("ok 12 - csqrt\n"); 284177763Sdas 285177763Sdas test_infinities(); 286177763Sdas printf("ok 13 - csqrt\n"); 287177763Sdas 288177763Sdas test_nans(); 289177763Sdas printf("ok 14 - csqrt\n"); 290177763Sdas 291177763Sdas test_overflow(LDBL_MAX_EXP); 292177763Sdas printf("ok 15 - csqrt\n"); 293177763Sdas 294174619Sdas return (0); 295174619Sdas} 296