Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: src/rempio2.cc

Issue 303753002: Trigonometric functions using fdlibm. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: test case Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/math.js ('K') | « src/rempio2.h ('k') | src/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // ====================================================
6 // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
7 //
8 // Developed at SunSoft, a Sun Microsystems, Inc. business.
9 // Permission to use, copy, modify, and distribute this
10 // software is freely granted, provided that this notice
11 // is preserved.
12 // ====================================================
13 //
14 // The following is adapted from fdlibm (http://www.netlib.org/fdlibm).
15
16 #include "v8.h"
17
18 #include "double.h"
19 #include "rempio2.h"
20
21
22 namespace v8 {
23 namespace internal {
24
25 /*
26 * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
27 */
28 static const int two_over_pi[] = { 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1,
29 0xF534DD, 0xC0DB62, 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7,
30 0x246E3A, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
31 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, 0x3991D6,
32 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F,
33 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E,
34 0x5FEA2D, 0x7527BA, 0xC7EBE5, 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB,
35 0x5FB11F, 0x8D5D08, 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436,
36 0x1DA9E3, 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
37 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B };
38
39 static const double zero = 0.00000000000000000000e+00;
40 static const double two24 = 1.67772160000000000000e+07;
41
42 static const double PIo2[] = {
43 1.57079625129699707031e+00, // 0x3FF921FB, 0x40000000
44 7.54978941586159635335e-08, // 0x3E74442D, 0x00000000
45 5.39030252995776476554e-15, // 0x3CF84698, 0x80000000
46 3.28200341580791294123e-22, // 0x3B78CC51, 0x60000000
47 1.27065575308067607349e-29, // 0x39F01B83, 0x80000000
48 1.22933308981111328932e-36, // 0x387A2520, 0x40000000
49 2.73370053816464559624e-44, // 0x36E38222, 0x80000000
50 2.16741683877804819444e-51 // 0x3569F31D, 0x00000000
51 };
52
53 static const double one = 1.0;
54 static const double twon24 = 5.96046447753906250000e-08;
55
56 int __kernel_rem_pio2(double* x, double* y, int e0, int nx) {
57 static const int32_t jk = 3;
58 double fw;
59 int32_t jx = nx - 1;
60 int32_t jv = (e0 - 3) / 24;
61 if (jv < 0) jv = 0;
62 int32_t q0 = e0 - 24 * (jv + 1);
63 int32_t m = jx + jk;
64
65 double f[10];
66 for (int i = 0, j = jv - jx; i <= m; i++, j++) {
67 f[i] = (j < 0) ? zero : static_cast<double>(two_over_pi[j]);
68 }
69
70 double q[10];
71 for (int i = 0; i <= jk; i++) {
72 fw = 0.0;
73 for (int j = 0; j <= jx; j++) fw += x[j] * f[jx + i - j];
74 q[i] = fw;
75 }
76
77 int32_t jz = jk;
78
79 recompute:
80
81 int32_t iq[10];
82 double z = q[jz];
83 for (int i = 0, j = jz; j > 0; i++, j--) {
84 fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
85 iq[i] = static_cast<int32_t>(z - two24 * fw);
86 z = q[j - 1] + fw;
87 }
88
89 z = scalbn(z, q0);
90 z -= 8.0 * std::floor(z * 0.125);
91 int32_t n = static_cast<int32_t>(z);
92 z -= static_cast<double>(n);
93 int32_t ih = 0;
94 if (q0 > 0) {
95 int32_t i = (iq[jz - 1] >> (24 - q0));
96 n += i;
97 iq[jz - 1] -= i << (24 - q0);
98 ih = iq[jz - 1] >> (23 - q0);
99 } else if (q0 == 0) {
100 ih = iq[jz - 1] >> 23;
101 } else if (z >= 0.5) {
102 ih = 2;
103 }
104
105 if (ih > 0) {
106 n += 1;
107 int32_t carry = 0;
108 for (int i = 0; i < jz; i++) {
109 int32_t j = iq[i];
110 if (carry == 0) {
111 if (j != 0) {
112 carry = 1;
113 iq[i] = 0x1000000 - j;
114 }
115 } else {
116 iq[i] = 0xffffff - j;
117 }
118 }
119 if (q0 == 1) {
120 iq[jz - 1] &= 0x7fffff;
121 } else if (q0 == 2) {
122 iq[jz - 1] &= 0x3fffff;
123 }
124 if (ih == 2) {
125 z = one - z;
126 if (carry != 0) z -= scalbn(one, q0);
127 }
128 }
129
130 if (z == zero) {
131 int32_t j = 0;
132 for (int i = jz - 1; i >= jk; i--) j |= iq[i];
133 if (j == 0) {
134 int32_t k = 1;
135 while (iq[jk - k] == 0) k++;
136 for (int i = jz + 1; i <= jz + k; i++) {
137 f[jx + i] = static_cast<double>(two_over_pi[jv + i]);
138 for (j = 0, fw = 0.0; j <= jx; j++) fw += x[j] * f[jx + i - j];
139 q[i] = fw;
140 }
141 jz += k;
142 goto recompute;
143 }
144 }
145
146 if (z == 0.0) {
147 jz -= 1;
148 q0 -= 24;
149 while (iq[jz] == 0) {
150 jz--;
151 q0 -= 24;
152 }
153 } else {
154 z = scalbn(z, -q0);
155 if (z >= two24) {
156 fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
157 iq[jz] = static_cast<int32_t>(z - two24 * fw);
158 jz += 1;
159 q0 += 24;
160 iq[jz] = static_cast<int32_t>(fw);
161 } else {
162 iq[jz] = static_cast<int32_t>(z);
163 }
164 }
165
166 fw = scalbn(one, q0);
167 for (int i = jz; i >= 0; i--) {
168 q[i] = fw * static_cast<double>(iq[i]);
169 fw *= twon24;
170 }
171
172 double fq[10];
173 for (int i = jz; i >= 0; i--) {
174 fw = 0.0;
175 for (int k = 0; k <= jk && k <= jz - i; k++) fw += PIo2[k] * q[i + k];
176 fq[jz - i] = fw;
177 }
178
179 fw = 0.0;
180 for (int i = jz; i >= 0; i--) fw += fq[i];
181 y[0] = (ih == 0) ? fw : -fw;
182 fw = fq[0] - fw;
183 for (int i = 1; i <= jz; i++) fw += fq[i];
184 y[1] = (ih == 0) ? fw : -fw;
185 return n & 7;
186 }
187
188
189 int rempio2(double x, double* y) {
190 int32_t hx = static_cast<int32_t>(double_to_uint64(x) >> 32);
191 int32_t ix = hx & 0x7fffffff;
192
193 ASSERT(ix > 0x413921fb); // Handling of lower ix has been omitted.
194
195 int32_t e0 = (ix >> 20) - 1046;
196 uint64_t zi = double_to_uint64(x) & 0xFFFFFFFFu;
197 zi |= static_cast<uint64_t>(ix - (e0 << 20)) << 32;
198 double z = uint64_to_double(zi);
199
200 double tx[3];
201 for (int i = 0; i < 2; i++) {
202 tx[i] = static_cast<double>(static_cast<int32_t>(z));
203 z = (z - tx[i]) * two24;
204 }
205 tx[2] = z;
206
207 int nx = 3;
208 while (tx[nx - 1] == zero) nx--;
209 int n = __kernel_rem_pio2(tx, y, e0, nx);
210 if (hx < 0) {
211 y[0] = -y[0];
212 y[1] = -y[1];
213 return -n;
214 }
215 return n;
216 }
217
218 } } // namespace v8::internal
OLDNEW
« src/math.js ('K') | « src/rempio2.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698