1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci *
15425bb815Sopenharmony_ci * This file is based on work under the following copyright and permission
16425bb815Sopenharmony_ci * notice:
17425bb815Sopenharmony_ci *
18425bb815Sopenharmony_ci *     Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
19425bb815Sopenharmony_ci *
20425bb815Sopenharmony_ci *     Developed at SunSoft, a Sun Microsystems, Inc. business.
21425bb815Sopenharmony_ci *     Permission to use, copy, modify, and distribute this
22425bb815Sopenharmony_ci *     software is freely granted, provided that this notice
23425bb815Sopenharmony_ci *     is preserved.
24425bb815Sopenharmony_ci *
25425bb815Sopenharmony_ci *     @(#)s_cbrt.c 1.3 95/01/18
26425bb815Sopenharmony_ci */
27425bb815Sopenharmony_ci
28425bb815Sopenharmony_ci#include "jerry-libm-internal.h"
29425bb815Sopenharmony_ci
30425bb815Sopenharmony_ci/* cbrt(x)
31425bb815Sopenharmony_ci * Return cube root of x
32425bb815Sopenharmony_ci */
33425bb815Sopenharmony_ci
34425bb815Sopenharmony_ci#define B1 715094163 /* B1 = (682 - 0.03306235651) * 2**20 */
35425bb815Sopenharmony_ci#define B2 696219795 /* B2 = (664 - 0.03306235651) * 2**20 */
36425bb815Sopenharmony_ci#define C 5.42857142857142815906e-01  /* 19/35     = 0x3FE15F15, 0xF15F15F1 */
37425bb815Sopenharmony_ci#define D -7.05306122448979611050e-01 /* -864/1225 = 0xBFE691DE, 0x2532C834 */
38425bb815Sopenharmony_ci#define E 1.41428571428571436819e+00  /* 99/70     = 0x3FF6A0EA, 0x0EA0EA0F */
39425bb815Sopenharmony_ci#define F 1.60714285714285720630e+00  /* 45/28     = 0x3FF9B6DB, 0x6DB6DB6E */
40425bb815Sopenharmony_ci#define G 3.57142857142857150787e-01  /* 5/14      = 0x3FD6DB6D, 0xB6DB6DB7 */
41425bb815Sopenharmony_ci
42425bb815Sopenharmony_cidouble
43425bb815Sopenharmony_cicbrt (double x)
44425bb815Sopenharmony_ci{
45425bb815Sopenharmony_ci  double r, s, w;
46425bb815Sopenharmony_ci  double_accessor t, temp;
47425bb815Sopenharmony_ci  unsigned int sign;
48425bb815Sopenharmony_ci  t.dbl = 0.0;
49425bb815Sopenharmony_ci  temp.dbl = x;
50425bb815Sopenharmony_ci
51425bb815Sopenharmony_ci  sign = temp.as_int.hi & 0x80000000; /* sign = sign(x) */
52425bb815Sopenharmony_ci  temp.as_int.hi ^= sign;
53425bb815Sopenharmony_ci
54425bb815Sopenharmony_ci  if (temp.as_int.hi >= 0x7ff00000)
55425bb815Sopenharmony_ci  {
56425bb815Sopenharmony_ci    /* cbrt(NaN, INF) is itself */
57425bb815Sopenharmony_ci    return (x + x);
58425bb815Sopenharmony_ci  }
59425bb815Sopenharmony_ci  if ((temp.as_int.hi | temp.as_int.lo) == 0)
60425bb815Sopenharmony_ci  {
61425bb815Sopenharmony_ci    /* cbrt(0) is itself */
62425bb815Sopenharmony_ci    return (x);
63425bb815Sopenharmony_ci  }
64425bb815Sopenharmony_ci  /* rough cbrt to 5 bits */
65425bb815Sopenharmony_ci  if (temp.as_int.hi < 0x00100000) /* subnormal number */
66425bb815Sopenharmony_ci  {
67425bb815Sopenharmony_ci    t.as_int.hi = 0x43500000; /* set t= 2**54 */
68425bb815Sopenharmony_ci    t.dbl *= temp.dbl;
69425bb815Sopenharmony_ci    t.as_int.hi = t.as_int.hi / 3 + B2;
70425bb815Sopenharmony_ci  }
71425bb815Sopenharmony_ci  else
72425bb815Sopenharmony_ci  {
73425bb815Sopenharmony_ci    t.as_int.hi = temp.as_int.hi / 3 + B1;
74425bb815Sopenharmony_ci  }
75425bb815Sopenharmony_ci
76425bb815Sopenharmony_ci  /* new cbrt to 23 bits, may be implemented in single precision */
77425bb815Sopenharmony_ci  r = t.dbl * t.dbl / temp.dbl;
78425bb815Sopenharmony_ci  s = C + r * t.dbl;
79425bb815Sopenharmony_ci  t.dbl *= G + F / (s + E + D / s);
80425bb815Sopenharmony_ci
81425bb815Sopenharmony_ci  /* chopped to 20 bits and make it larger than cbrt(x) */
82425bb815Sopenharmony_ci  t.as_int.lo = 0;
83425bb815Sopenharmony_ci  t.as_int.hi += 0x00000001;
84425bb815Sopenharmony_ci
85425bb815Sopenharmony_ci  /* one step newton iteration to 53 bits with error less than 0.667 ulps */
86425bb815Sopenharmony_ci  s = t.dbl * t.dbl; /* t*t is exact */
87425bb815Sopenharmony_ci  r = temp.dbl / s;
88425bb815Sopenharmony_ci  w = t.dbl + t.dbl;
89425bb815Sopenharmony_ci  r = (r - t.dbl) / (w + r); /* r-s is exact */
90425bb815Sopenharmony_ci  t.dbl = t.dbl + (t.dbl * r);
91425bb815Sopenharmony_ci
92425bb815Sopenharmony_ci  /* retore the sign bit */
93425bb815Sopenharmony_ci  t.as_int.hi |= sign;
94425bb815Sopenharmony_ci  return (t.dbl);
95425bb815Sopenharmony_ci} /* cbrt */
96425bb815Sopenharmony_ci
97425bb815Sopenharmony_ci#undef B1
98425bb815Sopenharmony_ci#undef B2
99425bb815Sopenharmony_ci#undef C
100425bb815Sopenharmony_ci#undef D
101425bb815Sopenharmony_ci#undef E
102425bb815Sopenharmony_ci#undef F
103425bb815Sopenharmony_ci#undef G
104