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