blob: b193176b412c50b6323634e198ed11b55f61a980 [file] [log] [blame]
Kai Tietz53b69ff2007-08-20 13:49:15 +00001/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the w64 mingw-runtime package.
4 * No warranty is given; refer to the file DISCLAIMER within this package.
5 */
Kai Tietz518dd332007-08-10 09:54:15 +00006#include "cephes_mconf.h"
7
8static const long double CBRT2 = 1.2599210498948731647672L;
9static const long double CBRT4 = 1.5874010519681994747517L;
10static const long double CBRT2I = 0.79370052598409973737585L;
11static const long double CBRT4I = 0.62996052494743658238361L;
12
Kai Tietz3c6bbdb2007-09-10 12:53:13 +000013extern long double ldexpl(long double,int);
14
Kai Tietz518dd332007-08-10 09:54:15 +000015long double cbrtl(x)
16long double x;
17{
18int e, rem, sign;
19long double z;
20
21if (!isfinite (x) || x == 0.0L)
22 return(x);
23
24if( x > 0 )
25 sign = 1;
26else
27 {
28 sign = -1;
29 x = -x;
30 }
31
32z = x;
33/* extract power of 2, leaving
34 * mantissa between 0.5 and 1
35 */
36x = frexpl( x, &e );
37
38/* Approximate cube root of number between .5 and 1,
39 * peak relative error = 1.2e-6
40 */
41x = (((( 1.3584464340920900529734e-1L * x
42 - 6.3986917220457538402318e-1L) * x
43 + 1.2875551670318751538055e0L) * x
44 - 1.4897083391357284957891e0L) * x
45 + 1.3304961236013647092521e0L) * x
46 + 3.7568280825958912391243e-1L;
47
48/* exponent divided by 3 */
49if( e >= 0 )
50 {
51 rem = e;
52 e /= 3;
53 rem -= 3*e;
54 if( rem == 1 )
55 x *= CBRT2;
56 else if( rem == 2 )
57 x *= CBRT4;
58 }
59else
60 { /* argument less than 1 */
61 e = -e;
62 rem = e;
63 e /= 3;
64 rem -= 3*e;
65 if( rem == 1 )
66 x *= CBRT2I;
67 else if( rem == 2 )
68 x *= CBRT4I;
69 e = -e;
70 }
71
72/* multiply by power of 2 */
73x = ldexpl( x, e );
74
75/* Newton iteration */
76
77x -= ( x - (z/(x*x)) )*0.3333333333333333333333L;
78x -= ( x - (z/(x*x)) )*0.3333333333333333333333L;
79
80if( sign < 0 )
81 x = -x;
82return(x);
83}