1 1.1 mrg /* cbrtq.c 2 1.1 mrg * 3 1.1 mrg * Cube root, long double precision 4 1.1 mrg * 5 1.1 mrg * 6 1.1 mrg * 7 1.1 mrg * SYNOPSIS: 8 1.1 mrg * 9 1.1 mrg * long double x, y, cbrtq(); 10 1.1 mrg * 11 1.1 mrg * y = cbrtq( x ); 12 1.1 mrg * 13 1.1 mrg * 14 1.1 mrg * 15 1.1 mrg * DESCRIPTION: 16 1.1 mrg * 17 1.1 mrg * Returns the cube root of the argument, which may be negative. 18 1.1 mrg * 19 1.1 mrg * Range reduction involves determining the power of 2 of 20 1.1 mrg * the argument. A polynomial of degree 2 applied to the 21 1.1 mrg * mantissa, and multiplication by the cube root of 1, 2, or 4 22 1.1 mrg * approximates the root to within about 0.1%. Then Newton's 23 1.1 mrg * iteration is used three times to converge to an accurate 24 1.1 mrg * result. 25 1.1 mrg * 26 1.1 mrg * 27 1.1 mrg * 28 1.1 mrg * ACCURACY: 29 1.1 mrg * 30 1.1 mrg * Relative error: 31 1.1 mrg * arithmetic domain # trials peak rms 32 1.1 mrg * IEEE -8,8 100000 1.3e-34 3.9e-35 33 1.1 mrg * IEEE exp(+-707) 100000 1.3e-34 4.3e-35 34 1.1 mrg * 35 1.1 mrg */ 36 1.1 mrg 37 1.1 mrg /* 38 1.1 mrg Cephes Math Library Release 2.2: January, 1991 39 1.1 mrg Copyright 1984, 1991 by Stephen L. Moshier 40 1.1 mrg Adapted for glibc October, 2001. 41 1.1 mrg 42 1.1 mrg This library is free software; you can redistribute it and/or 43 1.1 mrg modify it under the terms of the GNU Lesser General Public 44 1.1 mrg License as published by the Free Software Foundation; either 45 1.1 mrg version 2.1 of the License, or (at your option) any later version. 46 1.1 mrg 47 1.1 mrg This library is distributed in the hope that it will be useful, 48 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 49 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 50 1.1 mrg Lesser General Public License for more details. 51 1.1 mrg 52 1.1 mrg You should have received a copy of the GNU Lesser General Public 53 1.1 mrg License along with this library; if not, see 54 1.1 mrg <http://www.gnu.org/licenses/>. */ 55 1.1 mrg 56 1.1 mrg #include "quadmath-imp.h" 57 1.1 mrg 58 1.1 mrg static const __float128 CBRT2 = 1.259921049894873164767210607278228350570251Q; 59 1.1 mrg static const __float128 CBRT4 = 1.587401051968199474751705639272308260391493Q; 60 1.1 mrg static const __float128 CBRT2I = 0.7937005259840997373758528196361541301957467Q; 61 1.1 mrg static const __float128 CBRT4I = 0.6299605249474365823836053036391141752851257Q; 62 1.1 mrg 63 1.1 mrg 64 1.1 mrg __float128 65 1.1 mrg cbrtq (__float128 x) 66 1.1 mrg { 67 1.1 mrg int e, rem, sign; 68 1.1 mrg __float128 z; 69 1.1 mrg 70 1.1 mrg if (!finiteq (x)) 71 1.1 mrg return x + x; 72 1.1 mrg 73 1.1 mrg if (x == 0) 74 1.1 mrg return (x); 75 1.1 mrg 76 1.1 mrg if (x > 0) 77 1.1 mrg sign = 1; 78 1.1 mrg else 79 1.1 mrg { 80 1.1 mrg sign = -1; 81 1.1 mrg x = -x; 82 1.1 mrg } 83 1.1 mrg 84 1.1 mrg z = x; 85 1.1 mrg /* extract power of 2, leaving mantissa between 0.5 and 1 */ 86 1.1 mrg x = frexpq (x, &e); 87 1.1 mrg 88 1.1 mrg /* Approximate cube root of number between .5 and 1, 89 1.1 mrg peak relative error = 1.2e-6 */ 90 1.1 mrg x = ((((1.3584464340920900529734e-1Q * x 91 1.1 mrg - 6.3986917220457538402318e-1Q) * x 92 1.1 mrg + 1.2875551670318751538055e0Q) * x 93 1.1 mrg - 1.4897083391357284957891e0Q) * x 94 1.1 mrg + 1.3304961236013647092521e0Q) * x + 3.7568280825958912391243e-1Q; 95 1.1 mrg 96 1.1 mrg /* exponent divided by 3 */ 97 1.1 mrg if (e >= 0) 98 1.1 mrg { 99 1.1 mrg rem = e; 100 1.1 mrg e /= 3; 101 1.1 mrg rem -= 3 * e; 102 1.1 mrg if (rem == 1) 103 1.1 mrg x *= CBRT2; 104 1.1 mrg else if (rem == 2) 105 1.1 mrg x *= CBRT4; 106 1.1 mrg } 107 1.1 mrg else 108 1.1 mrg { /* argument less than 1 */ 109 1.1 mrg e = -e; 110 1.1 mrg rem = e; 111 1.1 mrg e /= 3; 112 1.1 mrg rem -= 3 * e; 113 1.1 mrg if (rem == 1) 114 1.1 mrg x *= CBRT2I; 115 1.1 mrg else if (rem == 2) 116 1.1 mrg x *= CBRT4I; 117 1.1 mrg e = -e; 118 1.1 mrg } 119 1.1 mrg 120 1.1 mrg /* multiply by power of 2 */ 121 1.1 mrg x = ldexpq (x, e); 122 1.1 mrg 123 1.1 mrg /* Newton iteration */ 124 1.1 mrg x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333Q; 125 1.1 mrg x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333Q; 126 1.1 mrg x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333Q; 127 1.1 mrg 128 1.1 mrg if (sign < 0) 129 1.1 mrg x = -x; 130 1.1 mrg return (x); 131 1.1 mrg } 132