125c28e83SPiotr Jasiukajtis /* 225c28e83SPiotr Jasiukajtis * CDDL HEADER START 325c28e83SPiotr Jasiukajtis * 425c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the 525c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License"). 625c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License. 725c28e83SPiotr Jasiukajtis * 825c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 925c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing. 1025c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions 1125c28e83SPiotr Jasiukajtis * and limitations under the License. 1225c28e83SPiotr Jasiukajtis * 1325c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each 1425c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1525c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the 1625c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying 1725c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner] 1825c28e83SPiotr Jasiukajtis * 1925c28e83SPiotr Jasiukajtis * CDDL HEADER END 2025c28e83SPiotr Jasiukajtis */ 2125c28e83SPiotr Jasiukajtis 2225c28e83SPiotr Jasiukajtis /* 2325c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 2425c28e83SPiotr Jasiukajtis */ 2525c28e83SPiotr Jasiukajtis /* 2625c28e83SPiotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2725c28e83SPiotr Jasiukajtis * Use is subject to license terms. 2825c28e83SPiotr Jasiukajtis */ 2925c28e83SPiotr Jasiukajtis 30*ddc0e0b5SRichard Lowe #pragma weak __csqrtl = csqrtl 3125c28e83SPiotr Jasiukajtis 3225c28e83SPiotr Jasiukajtis #include "libm.h" /* fabsl/isinfl/sqrtl */ 3325c28e83SPiotr Jasiukajtis #include "complex_wrapper.h" 3425c28e83SPiotr Jasiukajtis #include "longdouble.h" 3525c28e83SPiotr Jasiukajtis 3625c28e83SPiotr Jasiukajtis /* INDENT OFF */ 3725c28e83SPiotr Jasiukajtis static const long double 3825c28e83SPiotr Jasiukajtis twom9001 = 2.6854002716003034957421765100615693043656e-2710L, 3925c28e83SPiotr Jasiukajtis twom4500 = 2.3174987687592429423263242862381544149252e-1355L, 4025c28e83SPiotr Jasiukajtis two8999 = 9.3095991180122343502582347372163290310934e+2708L, 4125c28e83SPiotr Jasiukajtis two4500 = 4.3149968987270974283777803545571722250806e+1354L, 4225c28e83SPiotr Jasiukajtis zero = 0.0L, 4325c28e83SPiotr Jasiukajtis half = 0.5L, 4425c28e83SPiotr Jasiukajtis two = 2.0L; 4525c28e83SPiotr Jasiukajtis /* INDENT ON */ 4625c28e83SPiotr Jasiukajtis 4725c28e83SPiotr Jasiukajtis ldcomplex 4825c28e83SPiotr Jasiukajtis csqrtl(ldcomplex z) { 4925c28e83SPiotr Jasiukajtis ldcomplex ans; 5025c28e83SPiotr Jasiukajtis long double x, y, t, ax, ay; 5125c28e83SPiotr Jasiukajtis int n, ix, iy, hx, hy; 5225c28e83SPiotr Jasiukajtis 5325c28e83SPiotr Jasiukajtis x = LD_RE(z); 5425c28e83SPiotr Jasiukajtis y = LD_IM(z); 5525c28e83SPiotr Jasiukajtis hx = HI_XWORD(x); 5625c28e83SPiotr Jasiukajtis hy = HI_XWORD(y); 5725c28e83SPiotr Jasiukajtis ix = hx & 0x7fffffff; 5825c28e83SPiotr Jasiukajtis iy = hy & 0x7fffffff; 5925c28e83SPiotr Jasiukajtis ay = fabsl(y); 6025c28e83SPiotr Jasiukajtis ax = fabsl(x); 6125c28e83SPiotr Jasiukajtis if (ix >= 0x7fff0000 || iy >= 0x7fff0000) { 6225c28e83SPiotr Jasiukajtis /* x or y is Inf or NaN */ 6325c28e83SPiotr Jasiukajtis if (isinfl(y)) 6425c28e83SPiotr Jasiukajtis LD_IM(ans) = LD_RE(ans) = ay; 6525c28e83SPiotr Jasiukajtis else if (isinfl(x)) { 6625c28e83SPiotr Jasiukajtis if (hx > 0) { 6725c28e83SPiotr Jasiukajtis LD_RE(ans) = ax; 6825c28e83SPiotr Jasiukajtis LD_IM(ans) = ay * zero; 6925c28e83SPiotr Jasiukajtis } else { 7025c28e83SPiotr Jasiukajtis LD_RE(ans) = ay * zero; 7125c28e83SPiotr Jasiukajtis LD_IM(ans) = ax; 7225c28e83SPiotr Jasiukajtis } 7325c28e83SPiotr Jasiukajtis } else 7425c28e83SPiotr Jasiukajtis LD_IM(ans) = LD_RE(ans) = ax + ay; 7525c28e83SPiotr Jasiukajtis } else if (y == zero) { 7625c28e83SPiotr Jasiukajtis if (hx >= 0) { 7725c28e83SPiotr Jasiukajtis LD_RE(ans) = sqrtl(ax); 7825c28e83SPiotr Jasiukajtis LD_IM(ans) = zero; 7925c28e83SPiotr Jasiukajtis } else { 8025c28e83SPiotr Jasiukajtis LD_IM(ans) = sqrtl(ax); 8125c28e83SPiotr Jasiukajtis LD_RE(ans) = zero; 8225c28e83SPiotr Jasiukajtis } 8325c28e83SPiotr Jasiukajtis } else if (ix >= iy) { 8425c28e83SPiotr Jasiukajtis n = (ix - iy) >> 16; 8525c28e83SPiotr Jasiukajtis #if defined(__x86) /* 64 significant bits */ 8625c28e83SPiotr Jasiukajtis if (n >= 35) 8725c28e83SPiotr Jasiukajtis #else /* 113 significant bits */ 8825c28e83SPiotr Jasiukajtis if (n >= 60) 8925c28e83SPiotr Jasiukajtis #endif 9025c28e83SPiotr Jasiukajtis t = sqrtl(ax); 9125c28e83SPiotr Jasiukajtis else if (ix >= 0x5f3f0000) { /* x > 2**8000 */ 9225c28e83SPiotr Jasiukajtis ax *= twom9001; 9325c28e83SPiotr Jasiukajtis y *= twom9001; 9425c28e83SPiotr Jasiukajtis t = two4500 * sqrtl(ax + sqrtl(ax * ax + y * y)); 9525c28e83SPiotr Jasiukajtis } else if (iy <= 0x20bf0000) { /* y < 2**-8000 */ 9625c28e83SPiotr Jasiukajtis ax *= two8999; 9725c28e83SPiotr Jasiukajtis y *= two8999; 9825c28e83SPiotr Jasiukajtis t = twom4500 * sqrtl(ax + sqrtl(ax * ax + y * y)); 9925c28e83SPiotr Jasiukajtis } else 10025c28e83SPiotr Jasiukajtis t = sqrtl(half * (ax + sqrtl(ax * ax + y * y))); 10125c28e83SPiotr Jasiukajtis 10225c28e83SPiotr Jasiukajtis if (hx >= 0) { 10325c28e83SPiotr Jasiukajtis LD_RE(ans) = t; 10425c28e83SPiotr Jasiukajtis LD_IM(ans) = ay / (t + t); 10525c28e83SPiotr Jasiukajtis } else { 10625c28e83SPiotr Jasiukajtis LD_IM(ans) = t; 10725c28e83SPiotr Jasiukajtis LD_RE(ans) = ay / (t + t); 10825c28e83SPiotr Jasiukajtis } 10925c28e83SPiotr Jasiukajtis } else { 11025c28e83SPiotr Jasiukajtis n = (iy - ix) >> 16; 11125c28e83SPiotr Jasiukajtis #if defined(__x86) /* 64 significant bits */ 11225c28e83SPiotr Jasiukajtis if (n >= 35) { /* } */ 11325c28e83SPiotr Jasiukajtis #else /* 113 significant bits */ 11425c28e83SPiotr Jasiukajtis if (n >= 60) { 11525c28e83SPiotr Jasiukajtis #endif 11625c28e83SPiotr Jasiukajtis if (n >= 120) 11725c28e83SPiotr Jasiukajtis t = sqrtl(half * ay); 11825c28e83SPiotr Jasiukajtis else if (iy >= 0x7ffe0000) 11925c28e83SPiotr Jasiukajtis t = sqrtl(half * ay + half * ax); 12025c28e83SPiotr Jasiukajtis else if (ix <= 0x00010000) 12125c28e83SPiotr Jasiukajtis t = half * (sqrtl(two * (ax + ay))); 12225c28e83SPiotr Jasiukajtis else 12325c28e83SPiotr Jasiukajtis t = sqrtl(half * (ax + ay)); 12425c28e83SPiotr Jasiukajtis } else if (iy >= 0x5f3f0000) { /* y > 2**8000 */ 12525c28e83SPiotr Jasiukajtis ax *= twom9001; 12625c28e83SPiotr Jasiukajtis y *= twom9001; 12725c28e83SPiotr Jasiukajtis t = two4500 * sqrtl(ax + sqrtl(ax * ax + y * y)); 12825c28e83SPiotr Jasiukajtis } else if (ix <= 0x20bf0000) { 12925c28e83SPiotr Jasiukajtis ax *= two8999; 13025c28e83SPiotr Jasiukajtis y *= two8999; 13125c28e83SPiotr Jasiukajtis t = twom4500 * sqrtl(ax + sqrtl(ax * ax + y * y)); 13225c28e83SPiotr Jasiukajtis } else 13325c28e83SPiotr Jasiukajtis t = sqrtl(half * (ax + sqrtl(ax * ax + y * y))); 13425c28e83SPiotr Jasiukajtis 13525c28e83SPiotr Jasiukajtis if (hx >= 0) { 13625c28e83SPiotr Jasiukajtis LD_RE(ans) = t; 13725c28e83SPiotr Jasiukajtis LD_IM(ans) = ay / (t + t); 13825c28e83SPiotr Jasiukajtis } else { 13925c28e83SPiotr Jasiukajtis LD_IM(ans) = t; 14025c28e83SPiotr Jasiukajtis LD_RE(ans) = ay / (t + t); 14125c28e83SPiotr Jasiukajtis } 14225c28e83SPiotr Jasiukajtis } 14325c28e83SPiotr Jasiukajtis if (hy < 0) 14425c28e83SPiotr Jasiukajtis LD_IM(ans) = -LD_IM(ans); 14525c28e83SPiotr Jasiukajtis return (ans); 14625c28e83SPiotr Jasiukajtis } 147