annotate libquadmath/math/cbrtq.c @ 158:494b0b89df80 default tip

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