home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / LIBC / LIBC-4.6 / LIBC-4 / libc-linux / sysdeps / linux / m68k / math / cbrt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-19  |  2.5 KB  |  98 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.  * Prototype changed for linux libc by flebbe@tat.physik.uni-tuebingen.de
  13.  * 15.3.94
  14.  * Pointer aliasing bug fixed by Stephen Moshier (moshier@world.std.com)
  15.  * 29.9.94
  16.  * Additional change by Olaf Flebbe.
  17. */
  18.  
  19. #include <ansidecl.h>
  20. #include <math.h>
  21.  
  22. /* cbrt(x)
  23.  * Return cube root of x
  24.  */
  25. #ifdef __STDC__
  26. static const unsigned 
  27. #else
  28. static unsigned 
  29. #endif
  30.     B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
  31.     B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
  32.  
  33. #ifdef __STDC__
  34. static const double
  35. #else
  36. static double
  37. #endif
  38. C =  5.42857142857142815906e-01, /* 19/35     = 0x3FE15F15, 0xF15F15F1 */
  39. D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
  40. E =  1.41428571428571436819e+00, /* 99/70     = 0x3FF6A0EA, 0x0EA0EA0F */
  41. F =  1.60714285714285720630e+00, /* 45/28     = 0x3FF9B6DB, 0x6DB6DB6E */
  42. G =  3.57142857142857150787e-01; /* 5/14      = 0x3FD6DB6D, 0xB6DB6DB7 */
  43.  
  44. /* Define n0 1 for little endian */
  45. /* Define n0 0 for big endian machines */
  46. #define n0 1
  47.  
  48. double DEFUN( cbrt, (x), double x) 
  49. {
  50.     int    hx;
  51.     double r,s,w;
  52.     unsigned sign;
  53.     union {
  54.            double t;
  55.            unsigned pt[2];
  56.         } ut, ux;
  57.  
  58.     ut.t = 0.0;
  59.         ux.t = x;
  60.  
  61.     hx = ux.pt[n0];                 /* high word of x */
  62.     sign=hx&0x80000000;         /* sign= sign(x) */
  63.     hx  ^=sign;
  64.     if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
  65.     if((hx| ux.pt[1-n0])==0) 
  66.         return(ux.t);                    /* cbrt(0) is itself */
  67.  
  68.         ux.pt[n0] = hx;
  69.     /* rough cbrt to 5 bits */
  70.     if(hx<0x00100000)         /* subnormal number */
  71.       {ut.pt[n0]=0x43500000;         /* set t= 2**54 */
  72.        ut.t*=x; ut.pt[n0]=ut.pt[n0]/3+B2;
  73.       }
  74.     else
  75.       ut.pt[n0]=hx/3+B1;
  76.  
  77.  
  78.     /* new cbrt to 23 bits, may be implemented in single precision */
  79.     r=ut.t*ut.t/ux.t;
  80.     s=C+r*ut.t;
  81.     ut.t*=G+F/(s+E+D/s);
  82.  
  83.     /* chopped to 20 bits and make it larger than cbrt(x) */ 
  84.     ut.pt[1-n0]=0; ut.pt[n0]+=0x00000001;
  85.  
  86.  
  87.     /* one step newton iteration to 53 bits with error less than 0.667 ulps */
  88.     s=ut.t*ut.t;        /* t*t is exact */
  89.     r=ux.t/s;
  90.     w=ut.t+ut.t;
  91.     r=(r-ut.t)/(w+r);    /* r-s is exact */
  92.     ut.t=ut.t+ut.t*r;
  93.  
  94.     /* restore the sign bit */
  95.     ut.pt[n0] |= sign;
  96.     return(ut.t);
  97. }
  98.