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 / i386 / math / cbrtl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-26  |  2.6 KB  |  103 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 "mathl.h"
  21.  
  22. /* cbrtl(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. long double DEFUN( cbrtl, (x), long double x) 
  49. {
  50.     int    hx;
  51.     double r,s,w;
  52.     long double lt;
  53.     unsigned sign;
  54.     union {
  55.            double t;
  56.            unsigned pt[2];
  57.         } ut, ux;
  58.  
  59.     ut.t = 0.0;
  60.         ux.t = x;
  61.  
  62.     hx = ux.pt[n0];                 /* high word of x */
  63.     sign=hx&0x80000000;         /* sign= sign(x) */
  64.     hx  ^=sign;
  65.     if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
  66.     if((hx| ux.pt[1-n0])==0) 
  67.         return(ux.t);                    /* cbrt(0) is itself */
  68.  
  69.         ux.pt[n0] = hx;
  70.     /* rough cbrt to 5 bits */
  71.     if(hx<0x00100000)         /* subnormal number */
  72.       {ut.pt[n0]=0x43500000;         /* set t= 2**54 */
  73.        ut.t*=x; ut.pt[n0]=ut.pt[n0]/3+B2;
  74.       }
  75.     else
  76.       ut.pt[n0]=hx/3+B1;
  77.  
  78.  
  79.     /* new cbrt to 23 bits, may be implemented in single precision */
  80.     r=ut.t*ut.t/ux.t;
  81.     s=C+r*ut.t;
  82.     ut.t*=G+F/(s+E+D/s);
  83.  
  84.     /* chopped to 20 bits and make it larger than cbrt(x) */ 
  85.     ut.pt[1-n0]=0; ut.pt[n0]+=0x00000001;
  86.  
  87.  
  88.     /* one step newton iteration to 53 bits with error less than 0.667 ulps */
  89.     s=ut.t*ut.t;        /* t*t is exact */
  90.     r=ux.t/s;
  91.     w=ut.t+ut.t;
  92.     r=(r-ut.t)/(w+r);    /* r-s is exact */
  93.     ut.t=ut.t+ut.t*r;
  94.  
  95.     
  96.     /* restore the sign bit */
  97.     ut.pt[n0] |= sign;
  98.  
  99.     lt = ut.t;
  100.     lt -= (lt - (x/(lt*lt))) * 0.333333333333333333333L;
  101.     return lt;
  102. }
  103.