OLD | NEW |
1 // The following is adapted from fdlibm (http://www.netlib.org/fdlibm). | 1 // The following is adapted from fdlibm (http://www.netlib.org/fdlibm). |
2 // | 2 // |
3 // ==================================================== | 3 // ==================================================== |
4 // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | 4 // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
5 // | 5 // |
6 // Developed at SunSoft, a Sun Microsystems, Inc. business. | 6 // Developed at SunSoft, a Sun Microsystems, Inc. business. |
7 // Permission to use, copy, modify, and distribute this | 7 // Permission to use, copy, modify, and distribute this |
8 // software is freely granted, provided that this notice | 8 // software is freely granted, provided that this notice |
9 // is preserved. | 9 // is preserved. |
10 // ==================================================== | 10 // ==================================================== |
11 // | 11 // |
12 // The original source code covered by the above license above has been | 12 // The original source code covered by the above license above has been |
13 // modified significantly by Google Inc. | 13 // modified significantly by Google Inc. |
14 // Copyright 2016 the V8 project authors. All rights reserved. | 14 // Copyright 2016 the V8 project authors. All rights reserved. |
15 | 15 |
16 #include "src/base/ieee754.h" | 16 #include "src/base/ieee754.h" |
17 | 17 |
| 18 #include <cmath> |
18 #include <limits> | 19 #include <limits> |
19 | 20 |
20 #include "src/base/build_config.h" | 21 #include "src/base/build_config.h" |
21 #include "src/base/macros.h" | 22 #include "src/base/macros.h" |
22 | 23 |
23 namespace v8 { | 24 namespace v8 { |
24 namespace base { | 25 namespace base { |
25 namespace ieee754 { | 26 namespace ieee754 { |
26 | 27 |
27 namespace { | 28 namespace { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 sl_u.parts.lsw = (v); \ | 163 sl_u.parts.lsw = (v); \ |
163 (d) = sl_u.value; \ | 164 (d) = sl_u.value; \ |
164 } while (0) | 165 } while (0) |
165 | 166 |
166 /* Support macro. */ | 167 /* Support macro. */ |
167 | 168 |
168 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) | 169 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) |
169 | 170 |
170 } // namespace | 171 } // namespace |
171 | 172 |
| 173 /* atan(x) |
| 174 * Method |
| 175 * 1. Reduce x to positive by atan(x) = -atan(-x). |
| 176 * 2. According to the integer k=4t+0.25 chopped, t=x, the argument |
| 177 * is further reduced to one of the following intervals and the |
| 178 * arctangent of t is evaluated by the corresponding formula: |
| 179 * |
| 180 * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) |
| 181 * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) |
| 182 * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) |
| 183 * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) |
| 184 * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) |
| 185 * |
| 186 * Constants: |
| 187 * The hexadecimal values are the intended ones for the following |
| 188 * constants. The decimal values may be used, provided that the |
| 189 * compiler will convert from decimal to binary accurately enough |
| 190 * to produce the hexadecimal values shown. |
| 191 */ |
| 192 double atan(double x) { |
| 193 static const double atanhi[] = { |
| 194 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ |
| 195 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ |
| 196 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ |
| 197 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ |
| 198 }; |
| 199 |
| 200 static const double atanlo[] = { |
| 201 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ |
| 202 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ |
| 203 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ |
| 204 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ |
| 205 }; |
| 206 |
| 207 static const double aT[] = { |
| 208 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ |
| 209 -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ |
| 210 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ |
| 211 -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ |
| 212 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ |
| 213 -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ |
| 214 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ |
| 215 -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ |
| 216 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ |
| 217 -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ |
| 218 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ |
| 219 }; |
| 220 |
| 221 static const double one = 1.0, huge = 1.0e300; |
| 222 |
| 223 double w, s1, s2, z; |
| 224 int32_t ix, hx, id; |
| 225 |
| 226 GET_HIGH_WORD(hx, x); |
| 227 ix = hx & 0x7fffffff; |
| 228 if (ix >= 0x44100000) { /* if |x| >= 2^66 */ |
| 229 u_int32_t low; |
| 230 GET_LOW_WORD(low, x); |
| 231 if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (low != 0))) |
| 232 return x + x; /* NaN */ |
| 233 if (hx > 0) |
| 234 return atanhi[3] + *(volatile double *)&atanlo[3]; |
| 235 else |
| 236 return -atanhi[3] - *(volatile double *)&atanlo[3]; |
| 237 } |
| 238 if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ |
| 239 if (ix < 0x3e400000) { /* |x| < 2^-27 */ |
| 240 if (huge + x > one) return x; /* raise inexact */ |
| 241 } |
| 242 id = -1; |
| 243 } else { |
| 244 x = fabs(x); |
| 245 if (ix < 0x3ff30000) { /* |x| < 1.1875 */ |
| 246 if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ |
| 247 id = 0; |
| 248 x = (2.0 * x - one) / (2.0 + x); |
| 249 } else { /* 11/16<=|x|< 19/16 */ |
| 250 id = 1; |
| 251 x = (x - one) / (x + one); |
| 252 } |
| 253 } else { |
| 254 if (ix < 0x40038000) { /* |x| < 2.4375 */ |
| 255 id = 2; |
| 256 x = (x - 1.5) / (one + 1.5 * x); |
| 257 } else { /* 2.4375 <= |x| < 2^66 */ |
| 258 id = 3; |
| 259 x = -1.0 / x; |
| 260 } |
| 261 } |
| 262 } |
| 263 /* end of argument reduction */ |
| 264 z = x * x; |
| 265 w = z * z; |
| 266 /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ |
| 267 s1 = z * (aT[0] + |
| 268 w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10]))))); |
| 269 s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9])))); |
| 270 if (id < 0) { |
| 271 return x - x * (s1 + s2); |
| 272 } else { |
| 273 z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x); |
| 274 return (hx < 0) ? -z : z; |
| 275 } |
| 276 } |
| 277 |
| 278 /* atan2(y,x) |
| 279 * Method : |
| 280 * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). |
| 281 * 2. Reduce x to positive by (if x and y are unexceptional): |
| 282 * ARG (x+iy) = arctan(y/x) ... if x > 0, |
| 283 * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, |
| 284 * |
| 285 * Special cases: |
| 286 * |
| 287 * ATAN2((anything), NaN ) is NaN; |
| 288 * ATAN2(NAN , (anything) ) is NaN; |
| 289 * ATAN2(+-0, +(anything but NaN)) is +-0 ; |
| 290 * ATAN2(+-0, -(anything but NaN)) is +-pi ; |
| 291 * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; |
| 292 * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; |
| 293 * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; |
| 294 * ATAN2(+-INF,+INF ) is +-pi/4 ; |
| 295 * ATAN2(+-INF,-INF ) is +-3pi/4; |
| 296 * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; |
| 297 * |
| 298 * Constants: |
| 299 * The hexadecimal values are the intended ones for the following |
| 300 * constants. The decimal values may be used, provided that the |
| 301 * compiler will convert from decimal to binary accurately enough |
| 302 * to produce the hexadecimal values shown. |
| 303 */ |
| 304 double atan2(double y, double x) { |
| 305 static volatile double tiny = 1.0e-300; |
| 306 static const double |
| 307 zero = 0.0, |
| 308 pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ |
| 309 pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ |
| 310 pi = 3.1415926535897931160E+00; /* 0x400921FB, 0x54442D18 */ |
| 311 static volatile double pi_lo = |
| 312 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ |
| 313 |
| 314 double z; |
| 315 int32_t k, m, hx, hy, ix, iy; |
| 316 u_int32_t lx, ly; |
| 317 |
| 318 EXTRACT_WORDS(hx, lx, x); |
| 319 ix = hx & 0x7fffffff; |
| 320 EXTRACT_WORDS(hy, ly, y); |
| 321 iy = hy & 0x7fffffff; |
| 322 if (((ix | ((lx | -static_cast<int32_t>(lx)) >> 31)) > 0x7ff00000) || |
| 323 ((iy | ((ly | -static_cast<int32_t>(ly)) >> 31)) > 0x7ff00000)) { |
| 324 return x + y; /* x or y is NaN */ |
| 325 } |
| 326 if (((hx - 0x3ff00000) | lx) == 0) return atan(y); /* x=1.0 */ |
| 327 m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */ |
| 328 |
| 329 /* when y = 0 */ |
| 330 if ((iy | ly) == 0) { |
| 331 switch (m) { |
| 332 case 0: |
| 333 case 1: |
| 334 return y; /* atan(+-0,+anything)=+-0 */ |
| 335 case 2: |
| 336 return pi + tiny; /* atan(+0,-anything) = pi */ |
| 337 case 3: |
| 338 return -pi - tiny; /* atan(-0,-anything) =-pi */ |
| 339 } |
| 340 } |
| 341 /* when x = 0 */ |
| 342 if ((ix | lx) == 0) return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny; |
| 343 |
| 344 /* when x is INF */ |
| 345 if (ix == 0x7ff00000) { |
| 346 if (iy == 0x7ff00000) { |
| 347 switch (m) { |
| 348 case 0: |
| 349 return pi_o_4 + tiny; /* atan(+INF,+INF) */ |
| 350 case 1: |
| 351 return -pi_o_4 - tiny; /* atan(-INF,+INF) */ |
| 352 case 2: |
| 353 return 3.0 * pi_o_4 + tiny; /*atan(+INF,-INF)*/ |
| 354 case 3: |
| 355 return -3.0 * pi_o_4 - tiny; /*atan(-INF,-INF)*/ |
| 356 } |
| 357 } else { |
| 358 switch (m) { |
| 359 case 0: |
| 360 return zero; /* atan(+...,+INF) */ |
| 361 case 1: |
| 362 return -zero; /* atan(-...,+INF) */ |
| 363 case 2: |
| 364 return pi + tiny; /* atan(+...,-INF) */ |
| 365 case 3: |
| 366 return -pi - tiny; /* atan(-...,-INF) */ |
| 367 } |
| 368 } |
| 369 } |
| 370 /* when y is INF */ |
| 371 if (iy == 0x7ff00000) return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny; |
| 372 |
| 373 /* compute y/x */ |
| 374 k = (iy - ix) >> 20; |
| 375 if (k > 60) { /* |y/x| > 2**60 */ |
| 376 z = pi_o_2 + 0.5 * pi_lo; |
| 377 m &= 1; |
| 378 } else if (hx < 0 && k < -60) { |
| 379 z = 0.0; /* 0 > |y|/x > -2**-60 */ |
| 380 } else { |
| 381 z = atan(fabs(y / x)); /* safe to do y/x */ |
| 382 } |
| 383 switch (m) { |
| 384 case 0: |
| 385 return z; /* atan(+,+) */ |
| 386 case 1: |
| 387 return -z; /* atan(-,+) */ |
| 388 case 2: |
| 389 return pi - (z - pi_lo); /* atan(+,-) */ |
| 390 default: /* case 3 */ |
| 391 return (z - pi_lo) - pi; /* atan(-,-) */ |
| 392 } |
| 393 } |
| 394 |
172 /* log(x) | 395 /* log(x) |
173 * Return the logrithm of x | 396 * Return the logrithm of x |
174 * | 397 * |
175 * Method : | 398 * Method : |
176 * 1. Argument Reduction: find k and f such that | 399 * 1. Argument Reduction: find k and f such that |
177 * x = 2^k * (1+f), | 400 * x = 2^k * (1+f), |
178 * where sqrt(2)/2 < 1+f < sqrt(2) . | 401 * where sqrt(2)/2 < 1+f < sqrt(2) . |
179 * | 402 * |
180 * 2. Approximation of log(1+f). | 403 * 2. Approximation of log(1+f). |
181 * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) | 404 * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 z * (Lp2 + z * (Lp3 + z * (Lp4 + z * (Lp5 + z * (Lp6 + z * Lp7)))))); | 681 z * (Lp2 + z * (Lp3 + z * (Lp4 + z * (Lp5 + z * (Lp6 + z * Lp7)))))); |
459 if (k == 0) | 682 if (k == 0) |
460 return f - (hfsq - s * (hfsq + R)); | 683 return f - (hfsq - s * (hfsq + R)); |
461 else | 684 else |
462 return k * ln2_hi - ((hfsq - (s * (hfsq + R) + (k * ln2_lo + c))) - f); | 685 return k * ln2_hi - ((hfsq - (s * (hfsq + R) + (k * ln2_lo + c))) - f); |
463 } | 686 } |
464 | 687 |
465 } // namespace ieee754 | 688 } // namespace ieee754 |
466 } // namespace base | 689 } // namespace base |
467 } // namespace v8 | 690 } // namespace v8 |
OLD | NEW |