Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
  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. #if defined(LIBM_SCCS) && !defined(lint)
  15. static char rcsid[] = "$Id: s_cbrt.c,v 1.6 1994/08/18 23:06:25 jtc Exp $";
  16. #endif
  17.  
  18. #include "math.h"
  19. #include "math_private.h"
  20.  
  21. /* cbrt(x)
  22.  * Return cube root of x
  23.  */
  24. #ifdef __STDC__
  25. static const u_int32_t
  26. #else
  27. static u_int32_t
  28. #endif
  29.         B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
  30.         B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
  31.  
  32. #ifdef __STDC__
  33. static const double
  34. #else
  35. static double
  36. #endif
  37. C =  5.42857142857142815906e-01, /* 19/35     = 0x3FE15F15, 0xF15F15F1 */
  38. D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
  39. E =  1.41428571428571436819e+00, /* 99/70     = 0x3FF6A0EA, 0x0EA0EA0F */
  40. F =  1.60714285714285720630e+00, /* 45/28     = 0x3FF9B6DB, 0x6DB6DB6E */
  41. G =  3.57142857142857150787e-01; /* 5/14      = 0x3FD6DB6D, 0xB6DB6DB7 */
  42.  
  43. #ifdef __STDC__
  44.         double cbrt(double x)
  45. #else
  46.         double cbrt(x)
  47.         double x;
  48. #endif
  49. {
  50.         int32_t hx;
  51.         double r,s,t=0.0,w;
  52.         u_int32_t sign;
  53.         u_int32_t high,low;
  54.  
  55.         GET_HIGH_WORD(hx,x);
  56.         sign=hx&0x80000000;             /* sign= sign(x) */
  57.         hx  ^=sign;
  58.         if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
  59.         GET_LOW_WORD(low,x);
  60.         if((hx|low)==0)
  61.             return(x);          /* cbrt(0) is itself */
  62.  
  63.         SET_HIGH_WORD(x,hx);    /* x <- |x| */
  64.     /* rough cbrt to 5 bits */
  65.         if(hx<0x00100000)               /* subnormal number */
  66.           {SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */
  67.            t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2);
  68.           }
  69.         else
  70.           SET_HIGH_WORD(t,hx/3+B1);
  71.  
  72.  
  73.     /* new cbrt to 23 bits, may be implemented in single precision */
  74.         r=t*t/x;
  75.         s=C+r*t;
  76.         t*=G+F/(s+E+D/s);      
  77.  
  78.     /* chopped to 20 bits and make it larger than cbrt(x) */
  79.         GET_HIGH_WORD(high,t);
  80.         INSERT_WORDS(t,high+0x00000001,0);
  81.  
  82.  
  83.     /* one step newton iteration to 53 bits with error less than 0.667 ulps */
  84.         s=t*t;          /* t*t is exact */
  85.         r=x/s;
  86.         w=t+t;
  87.         r=(r-t)/(w+r);  /* r-s is exact */
  88.         t=t+t*r;
  89.  
  90.     /* retore the sign bit */
  91.         GET_HIGH_WORD(high,t);
  92.         SET_HIGH_WORD(t,high|sign);
  93.         return(t);
  94. }
  95.