home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 Mobile / Chip_Mobile_2001.iso / palm / hobby / palmoon / palmoon.EXE / s_cbrt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-04-13  |  2.5 KB  |  99 lines

  1. /* @(#)s_cbrt.c 5.1 93/09/24 */
  2. /*
  3.  * ====================================================
  4.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  5.  *
  6.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software is freely granted, provided that this notice
  9.  * is preserved.
  10.  * ====================================================
  11.  */
  12.  
  13. #if defined(LIBM_SCCS) && !defined(lint)
  14. static char rcsid[] = "$NetBSD: s_cbrt.c,v 1.8 1995/05/10 20:46:49 jtc Exp $";
  15. #endif
  16.  
  17. #include "math.h"
  18. #include "math_private.h"
  19.  
  20. /* cbrt(x)
  21.  * Return cube root of x
  22.  */
  23. #ifdef __STDC__
  24. static const u_int32_t
  25. #else
  26. static u_int32_t
  27. #endif
  28.     B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
  29.     B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
  30.  
  31. #ifdef __STDC__
  32. static const double
  33. #else
  34. static double
  35. #endif
  36. C =  5.42857142857142815906e-01, /* 19/35     = 0x3FE15F15, 0xF15F15F1 */
  37. D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
  38. E =  1.41428571428571436819e+00, /* 99/70     = 0x3FF6A0EA, 0x0EA0EA0F */
  39. F =  1.60714285714285720630e+00, /* 45/28     = 0x3FF9B6DB, 0x6DB6DB6E */
  40. G =  3.57142857142857150787e-01; /* 5/14      = 0x3FD6DB6D, 0xB6DB6DB7 */
  41.  
  42. #ifdef __STDC__
  43.     double __cbrt(double x)
  44. #else
  45.     double __cbrt(x)
  46.     double x;
  47. #endif
  48. {
  49.     int32_t    hx;
  50.     double r,s,t=0.0,w;
  51.     u_int32_t sign;
  52.     u_int32_t high,low;
  53.  
  54.     GET_HIGH_WORD(hx,x);
  55.     sign=hx&0x80000000;         /* sign= sign(x) */
  56.     hx  ^=sign;
  57.     if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
  58.     GET_LOW_WORD(low,x);
  59.     if((hx|low)==0)
  60.         return(x);        /* cbrt(0) is itself */
  61.  
  62.     SET_HIGH_WORD(x,hx);    /* x <- |x| */
  63.     /* rough cbrt to 5 bits */
  64.     if(hx<0x00100000)         /* subnormal number */
  65.       {SET_HIGH_WORD(t,0x43500000);    /* set t= 2**54 */
  66.        t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2);
  67.       }
  68.     else
  69.       SET_HIGH_WORD(t,hx/3+B1);
  70.  
  71.  
  72.     /* new cbrt to 23 bits, may be implemented in single precision */
  73.     r=t*t/x;
  74.     s=C+r*t;
  75.     t*=G+F/(s+E+D/s);
  76.  
  77.     /* chopped to 20 bits and make it larger than cbrt(x) */
  78.     GET_HIGH_WORD(high,t);
  79.     INSERT_WORDS(t,high+0x00000001,0);
  80.  
  81.  
  82.     /* one step newton iteration to 53 bits with error less than 0.667 ulps */
  83.     s=t*t;        /* t*t is exact */
  84.     r=x/s;
  85.     w=t+t;
  86.     r=(r-t)/(w+r);    /* r-s is exact */
  87.     t=t+t*r;
  88.  
  89.     /* retore the sign bit */
  90.     GET_HIGH_WORD(high,t);
  91.     SET_HIGH_WORD(t,high|sign);
  92.     return(t);
  93. }
  94. weak_alias (__cbrt, cbrt)
  95. #ifdef NO_LONG_DOUBLE
  96. strong_alias (__cbrt, __cbrtl)
  97. weak_alias (__cbrt, cbrtl)
  98. #endif
  99.