Home | History | Annotate | Line # | Download | only in math
      1  1.1  mrg /*							cbrtq.c
      2  1.1  mrg  *
      3  1.1  mrg  *	Cube root, long double precision
      4  1.1  mrg  *
      5  1.1  mrg  *
      6  1.1  mrg  *
      7  1.1  mrg  * SYNOPSIS:
      8  1.1  mrg  *
      9  1.1  mrg  * long double x, y, cbrtq();
     10  1.1  mrg  *
     11  1.1  mrg  * y = cbrtq( x );
     12  1.1  mrg  *
     13  1.1  mrg  *
     14  1.1  mrg  *
     15  1.1  mrg  * DESCRIPTION:
     16  1.1  mrg  *
     17  1.1  mrg  * Returns the cube root of the argument, which may be negative.
     18  1.1  mrg  *
     19  1.1  mrg  * Range reduction involves determining the power of 2 of
     20  1.1  mrg  * the argument.  A polynomial of degree 2 applied to the
     21  1.1  mrg  * mantissa, and multiplication by the cube root of 1, 2, or 4
     22  1.1  mrg  * approximates the root to within about 0.1%.  Then Newton's
     23  1.1  mrg  * iteration is used three times to converge to an accurate
     24  1.1  mrg  * result.
     25  1.1  mrg  *
     26  1.1  mrg  *
     27  1.1  mrg  *
     28  1.1  mrg  * ACCURACY:
     29  1.1  mrg  *
     30  1.1  mrg  *                      Relative error:
     31  1.1  mrg  * arithmetic   domain     # trials      peak         rms
     32  1.1  mrg  *    IEEE       -8,8       100000      1.3e-34     3.9e-35
     33  1.1  mrg  *    IEEE    exp(+-707)    100000      1.3e-34     4.3e-35
     34  1.1  mrg  *
     35  1.1  mrg  */
     36  1.1  mrg 
     37  1.1  mrg /*
     38  1.1  mrg Cephes Math Library Release 2.2: January, 1991
     39  1.1  mrg Copyright 1984, 1991 by Stephen L. Moshier
     40  1.1  mrg Adapted for glibc October, 2001.
     41  1.1  mrg 
     42  1.1  mrg     This library is free software; you can redistribute it and/or
     43  1.1  mrg     modify it under the terms of the GNU Lesser General Public
     44  1.1  mrg     License as published by the Free Software Foundation; either
     45  1.1  mrg     version 2.1 of the License, or (at your option) any later version.
     46  1.1  mrg 
     47  1.1  mrg     This library is distributed in the hope that it will be useful,
     48  1.1  mrg     but WITHOUT ANY WARRANTY; without even the implied warranty of
     49  1.1  mrg     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     50  1.1  mrg     Lesser General Public License for more details.
     51  1.1  mrg 
     52  1.1  mrg     You should have received a copy of the GNU Lesser General Public
     53  1.1  mrg     License along with this library; if not, see
     54  1.1  mrg     <http://www.gnu.org/licenses/>.  */
     55  1.1  mrg 
     56  1.1  mrg #include "quadmath-imp.h"
     57  1.1  mrg 
     58  1.1  mrg static const __float128 CBRT2 = 1.259921049894873164767210607278228350570251Q;
     59  1.1  mrg static const __float128 CBRT4 = 1.587401051968199474751705639272308260391493Q;
     60  1.1  mrg static const __float128 CBRT2I = 0.7937005259840997373758528196361541301957467Q;
     61  1.1  mrg static const __float128 CBRT4I = 0.6299605249474365823836053036391141752851257Q;
     62  1.1  mrg 
     63  1.1  mrg 
     64  1.1  mrg __float128
     65  1.1  mrg cbrtq (__float128 x)
     66  1.1  mrg {
     67  1.1  mrg   int e, rem, sign;
     68  1.1  mrg   __float128 z;
     69  1.1  mrg 
     70  1.1  mrg   if (!finiteq (x))
     71  1.1  mrg     return x + x;
     72  1.1  mrg 
     73  1.1  mrg   if (x == 0)
     74  1.1  mrg     return (x);
     75  1.1  mrg 
     76  1.1  mrg   if (x > 0)
     77  1.1  mrg     sign = 1;
     78  1.1  mrg   else
     79  1.1  mrg     {
     80  1.1  mrg       sign = -1;
     81  1.1  mrg       x = -x;
     82  1.1  mrg     }
     83  1.1  mrg 
     84  1.1  mrg   z = x;
     85  1.1  mrg  /* extract power of 2, leaving mantissa between 0.5 and 1  */
     86  1.1  mrg   x = frexpq (x, &e);
     87  1.1  mrg 
     88  1.1  mrg   /* Approximate cube root of number between .5 and 1,
     89  1.1  mrg      peak relative error = 1.2e-6  */
     90  1.1  mrg   x = ((((1.3584464340920900529734e-1Q * x
     91  1.1  mrg 	  - 6.3986917220457538402318e-1Q) * x
     92  1.1  mrg 	 + 1.2875551670318751538055e0Q) * x
     93  1.1  mrg 	- 1.4897083391357284957891e0Q) * x
     94  1.1  mrg        + 1.3304961236013647092521e0Q) * x + 3.7568280825958912391243e-1Q;
     95  1.1  mrg 
     96  1.1  mrg   /* exponent divided by 3 */
     97  1.1  mrg   if (e >= 0)
     98  1.1  mrg     {
     99  1.1  mrg       rem = e;
    100  1.1  mrg       e /= 3;
    101  1.1  mrg       rem -= 3 * e;
    102  1.1  mrg       if (rem == 1)
    103  1.1  mrg 	x *= CBRT2;
    104  1.1  mrg       else if (rem == 2)
    105  1.1  mrg 	x *= CBRT4;
    106  1.1  mrg     }
    107  1.1  mrg   else
    108  1.1  mrg     {				/* argument less than 1 */
    109  1.1  mrg       e = -e;
    110  1.1  mrg       rem = e;
    111  1.1  mrg       e /= 3;
    112  1.1  mrg       rem -= 3 * e;
    113  1.1  mrg       if (rem == 1)
    114  1.1  mrg 	x *= CBRT2I;
    115  1.1  mrg       else if (rem == 2)
    116  1.1  mrg 	x *= CBRT4I;
    117  1.1  mrg       e = -e;
    118  1.1  mrg     }
    119  1.1  mrg 
    120  1.1  mrg   /* multiply by power of 2 */
    121  1.1  mrg   x = ldexpq (x, e);
    122  1.1  mrg 
    123  1.1  mrg   /* Newton iteration */
    124  1.1  mrg   x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333Q;
    125  1.1  mrg   x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333Q;
    126  1.1  mrg   x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333Q;
    127  1.1  mrg 
    128  1.1  mrg   if (sign < 0)
    129  1.1  mrg     x = -x;
    130  1.1  mrg   return (x);
    131  1.1  mrg }
    132