source: trunk/libs/newlib/src/newlib/libm/common/s_cbrt.c @ 620

Last change on this file since 620 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.6 KB
Line 
1
2/* @(#)s_cbrt.c 5.1 93/09/24 */
3/*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 *
7 * Developed at SunPro, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 *
13 */
14
15/*
16FUNCTION
17        <<cbrt>>, <<cbrtf>>---cube root
18
19INDEX
20        cbrt
21INDEX
22        cbrtf
23
24SYNOPSIS
25        #include <math.h>
26        double cbrt(double <[x]>);
27        float  cbrtf(float <[x]>);
28
29DESCRIPTION
30        <<cbrt>> computes the cube root of the argument.
31
32RETURNS
33        The cube root is returned.
34
35PORTABILITY
36        <<cbrt>> is in System V release 4.  <<cbrtf>> is an extension.
37*/
38
39#include "fdlibm.h"
40
41#ifndef _DOUBLE_IS_32BITS
42
43/* cbrt(x)
44 * Return cube root of x
45 */
46#ifdef __STDC__
47static const __uint32_t
48#else
49static __uint32_t
50#endif
51        B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
52        B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
53
54#ifdef __STDC__
55static const double
56#else
57static double
58#endif
59C =  5.42857142857142815906e-01, /* 19/35     = 0x3FE15F15, 0xF15F15F1 */
60D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
61E =  1.41428571428571436819e+00, /* 99/70     = 0x3FF6A0EA, 0x0EA0EA0F */
62F =  1.60714285714285720630e+00, /* 45/28     = 0x3FF9B6DB, 0x6DB6DB6E */
63G =  3.57142857142857150787e-01; /* 5/14      = 0x3FD6DB6D, 0xB6DB6DB7 */
64
65#ifdef __STDC__
66        double cbrt(double x) 
67#else
68        double cbrt(x) 
69        double x;
70#endif
71{
72        __int32_t       hx;
73        double r,s,t=0.0,w;
74        __uint32_t sign;
75        __uint32_t high,low;
76
77        GET_HIGH_WORD(hx,x);
78        sign=hx&0x80000000;             /* sign= sign(x) */
79        hx  ^=sign;
80        if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
81        GET_LOW_WORD(low,x);
82        if((hx|low)==0) 
83            return(x);          /* cbrt(0) is itself */
84
85        SET_HIGH_WORD(x,hx);    /* x <- |x| */
86    /* rough cbrt to 5 bits */
87        if(hx<0x00100000)               /* subnormal number */
88          {SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */
89           t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2);
90          }
91        else
92          SET_HIGH_WORD(t,hx/3+B1);
93
94
95    /* new cbrt to 23 bits, may be implemented in single precision */
96        r=t*t/x;
97        s=C+r*t;
98        t*=G+F/(s+E+D/s);       
99
100    /* chopped to 20 bits and make it larger than cbrt(x) */ 
101        GET_HIGH_WORD(high,t);
102        INSERT_WORDS(t,high+0x00000001,0);
103
104
105    /* one step newton iteration to 53 bits with error less than 0.667 ulps */
106        s=t*t;          /* t*t is exact */
107        r=x/s;
108        w=t+t;
109        r=(r-t)/(w+r);  /* r-s is exact */
110        t=t+t*r;
111
112    /* retore the sign bit */
113        GET_HIGH_WORD(high,t);
114        SET_HIGH_WORD(t,high|sign);
115        return(t);
116}
117
118#endif /* _DOUBLE_IS_32BITS */
Note: See TracBrowser for help on using the repository browser.