mirror of
https://gitea.nishi.boats/pyrite-dev/milsko
synced 2025-12-31 06:30:52 +00:00
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@557 b9cfdab3-6d41-4d17-bbe4-086880011989
73 lines
2.0 KiB
C
73 lines
2.0 KiB
C
|
|
/* @(#)s_cbrt.c 1.3 95/01/18 */
|
|
/*
|
|
* ====================================================
|
|
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
|
*
|
|
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
|
* Permission to use, copy, modify, and distribute this
|
|
* software is freely granted, provided that this notice
|
|
* is preserved.
|
|
* ====================================================
|
|
*
|
|
*/
|
|
|
|
#include "math.h"
|
|
|
|
/* cbrt(x)
|
|
* Return cube root of x
|
|
*/
|
|
static const unsigned
|
|
B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
|
|
B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
|
|
|
|
static const double
|
|
C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */
|
|
D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
|
|
E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */
|
|
F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */
|
|
G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */
|
|
|
|
double cbrt(double x) {
|
|
int hx;
|
|
double r, s, t = 0.0, w;
|
|
unsigned sign;
|
|
|
|
hx = __HI(x); /* high word of x */
|
|
sign = hx & 0x80000000; /* sign= sign(x) */
|
|
hx ^= sign;
|
|
if(hx >= 0x7ff00000) return (x + x); /* cbrt(NaN,INF) is itself */
|
|
if((hx | __LO(x)) == 0)
|
|
return (x); /* cbrt(0) is itself */
|
|
|
|
__HI(x) = hx; /* x <- |x| */
|
|
/* rough cbrt to 5 bits */
|
|
if(hx < 0x00100000) /* subnormal number */
|
|
{
|
|
__HI(t) = 0x43500000; /* set t= 2**54 */
|
|
t *= x;
|
|
__HI(t) = __HI(t) / 3 + B2;
|
|
} else
|
|
__HI(t) = hx / 3 + B1;
|
|
|
|
/* new cbrt to 23 bits, may be implemented in single precision */
|
|
r = t * t / x;
|
|
s = C + r * t;
|
|
t *= G + F / (s + E + D / s);
|
|
|
|
/* chopped to 20 bits and make it larger than cbrt(x) */
|
|
__LO(t) = 0;
|
|
__HI(t) += 0x00000001;
|
|
|
|
/* one step newton iteration to 53 bits with error less than 0.667 ulps */
|
|
s = t * t; /* t*t is exact */
|
|
r = x / s;
|
|
w = t + t;
|
|
r = (r - t) / (w + r); /* r-s is exact */
|
|
t = t + t * r;
|
|
|
|
/* retore the sign bit */
|
|
__HI(t) |= sign;
|
|
return (t);
|
|
}
|