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