annotate libquadmath/math/cbrtq.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents 561a7518be6b
children 1830386684a0
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 *
kono
parents: 68
diff changeset
3 * Cube root, __float128 precision
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 *
kono
parents: 68
diff changeset
9 * __float128 x, y, cbrtq();
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
kono
parents: 68
diff changeset
56
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 #include "quadmath-imp.h"
111
kono
parents: 68
diff changeset
58
kono
parents: 68
diff changeset
59 static const __float128 CBRT2 = 1.259921049894873164767210607278228350570251Q;
kono
parents: 68
diff changeset
60 static const __float128 CBRT4 = 1.587401051968199474751705639272308260391493Q;
kono
parents: 68
diff changeset
61 static const __float128 CBRT2I = 0.7937005259840997373758528196361541301957467Q;
kono
parents: 68
diff changeset
62 static const __float128 CBRT4I = 0.6299605249474365823836053036391141752851257Q;
kono
parents: 68
diff changeset
63
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 __float128
111
kono
parents: 68
diff changeset
66 cbrtq ( __float128 x)
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 {
111
kono
parents: 68
diff changeset
68 int e, rem, sign;
kono
parents: 68
diff changeset
69 __float128 z;
kono
parents: 68
diff changeset
70
kono
parents: 68
diff changeset
71 if (!finiteq (x))
kono
parents: 68
diff changeset
72 return x + x;
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 if (x == 0)
111
kono
parents: 68
diff changeset
75 return (x);
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76
111
kono
parents: 68
diff changeset
77 if (x > 0)
kono
parents: 68
diff changeset
78 sign = 1;
kono
parents: 68
diff changeset
79 else
kono
parents: 68
diff changeset
80 {
kono
parents: 68
diff changeset
81 sign = -1;
kono
parents: 68
diff changeset
82 x = -x;
kono
parents: 68
diff changeset
83 }
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84
111
kono
parents: 68
diff changeset
85 z = x;
kono
parents: 68
diff changeset
86 /* extract power of 2, leaving mantissa between 0.5 and 1 */
kono
parents: 68
diff changeset
87 x = frexpq (x, &e);
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
111
kono
parents: 68
diff changeset
89 /* Approximate cube root of number between .5 and 1,
kono
parents: 68
diff changeset
90 peak relative error = 1.2e-6 */
kono
parents: 68
diff changeset
91 x = ((((1.3584464340920900529734e-1Q * x
kono
parents: 68
diff changeset
92 - 6.3986917220457538402318e-1Q) * x
kono
parents: 68
diff changeset
93 + 1.2875551670318751538055e0Q) * x
kono
parents: 68
diff changeset
94 - 1.4897083391357284957891e0Q) * x
kono
parents: 68
diff changeset
95 + 1.3304961236013647092521e0Q) * x + 3.7568280825958912391243e-1Q;
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96
111
kono
parents: 68
diff changeset
97 /* exponent divided by 3 */
kono
parents: 68
diff changeset
98 if (e >= 0)
kono
parents: 68
diff changeset
99 {
kono
parents: 68
diff changeset
100 rem = e;
kono
parents: 68
diff changeset
101 e /= 3;
kono
parents: 68
diff changeset
102 rem -= 3 * e;
kono
parents: 68
diff changeset
103 if (rem == 1)
kono
parents: 68
diff changeset
104 x *= CBRT2;
kono
parents: 68
diff changeset
105 else if (rem == 2)
kono
parents: 68
diff changeset
106 x *= CBRT4;
kono
parents: 68
diff changeset
107 }
kono
parents: 68
diff changeset
108 else
kono
parents: 68
diff changeset
109 { /* argument less than 1 */
kono
parents: 68
diff changeset
110 e = -e;
kono
parents: 68
diff changeset
111 rem = e;
kono
parents: 68
diff changeset
112 e /= 3;
kono
parents: 68
diff changeset
113 rem -= 3 * e;
kono
parents: 68
diff changeset
114 if (rem == 1)
kono
parents: 68
diff changeset
115 x *= CBRT2I;
kono
parents: 68
diff changeset
116 else if (rem == 2)
kono
parents: 68
diff changeset
117 x *= CBRT4I;
kono
parents: 68
diff changeset
118 e = -e;
kono
parents: 68
diff changeset
119 }
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120
111
kono
parents: 68
diff changeset
121 /* multiply by power of 2 */
kono
parents: 68
diff changeset
122 x = ldexpq (x, e);
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123
111
kono
parents: 68
diff changeset
124 /* Newton iteration */
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;
kono
parents: 68
diff changeset
127 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
128
111
kono
parents: 68
diff changeset
129 if (sign < 0)
kono
parents: 68
diff changeset
130 x = -x;
kono
parents: 68
diff changeset
131 return (x);
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 }