
/* @(#)e_sqrt.c 1.3 95/01/18 */
/*
 * ====================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 * Developed at SunSoft, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice 
 * is preserved.
 * ====================================================
 */

#ifndef lint
static char rcsid[] = "$FreeBSD: src/lib/msun/src/e_sqrt.c,v 1.10 2005/02/04 18:26:06 das Exp $";
#endif

/* __ieee754_sqrt(x)
 * Return correctly rounded sqrt.
 *           ------------------------------------------
 *	     |  Use the hardware sqrt if you have one |
 *           ------------------------------------------
 * Method: 
 *   Bit by bit method using integer arithmetic. (Slow, but portable) 
 *   1. Normalization
 *	Scale x to y in [1,4) with even powers of 2: 
 *	find an integer k such that  1 <= (y=x*2^(2k)) < 4, then
 *		sqrt(x) = 2^k * sqrt(y)
 *   2. Bit by bit computation
 *	Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
 *	     i							 0
 *                                     i+1         2
 *	    s  = 2*q , and	y  =  2   * ( y - q  ).		(1)
 *	     i      i            i                 i
 *                                                        
 *	To compute q    from q , one checks whether 
 *		    i+1       i                       
 *
 *			      -(i+1) 2
 *			(q + 2      ) <= y.			(2)
 *     			  i
 *							      -(i+1)
 *	If (2) is false, then q   = q ; otherwise q   = q  + 2      .
 *		 	       i+1   i             i+1   i
 *
 *	With some algebric manipulation, it is not difficult to see
 *	that (2) is equivalent to 
 *                             -(i+1)
 *			s  +  2       <= y			(3)
 *			 i                i
 *
 *	The advantage of (3) is that s  and y  can be computed by 
 *				      i      i
 *	the following recurrence formula:
 *	    if (3) is false
 *
 *	    s     =  s  ,	y    = y   ;			(4)
 *	     i+1      i		 i+1    i
 *
 *	    otherwise,
 *                         -i                     -(i+1)
 *	    s	  =  s  + 2  ,  y    = y  -  s  - 2  		(5)
 *           i+1      i          i+1    i     i
 *				
 *	One may easily use induction to prove (4) and (5). 
 *	Note. Since the left hand side of (3) contain only i+2 bits,
 *	      it does not necessary to do a full (53-bit) comparison 
 *	      in (3).
 *   3. Final rounding
 *	After generating the 53 bits result, we compute one more bit.
 *	Together with the remainder, we can decide whether the
 *	result is exact, bigger than 1/2ulp, or less than 1/2ulp
 *	(it will never equal to 1/2ulp).
 *	The rounding mode can be detected by checking whether
 *	huge + tiny is equal to huge, and whether huge - tiny is
 *	equal to huge for some floating point number "huge" and "tiny".
 *		
 * Special cases:
 *	sqrt(+-0) = +-0 	... exact
 *	sqrt(inf) = inf
 *	sqrt(-ve) = NaN		... with invalid signal
 *	sqrt(NaN) = NaN		... with invalid signal for signaling NaN
 *
 * Other methods : see the appended file at the end of the program below.
 *---------------
 */

#include "math.h"
#include "math_private.h"

static	const double	one	= 1.0, tiny=1.0e-300;

double
__ieee754_sqrt(double x)
{
	double z;
	int32_t sign = (int)0x80000000;
	int32_t ix0,s0,q,m,t,i;
	u_int32_t r,t1,s1,ix1,q1;

	EXTRACT_WORDS(ix0,ix1,x);

    /* take care of Inf and NaN */
	if((ix0&0x7ff00000)==0x7ff00000) {			
	    return x*x+x;		/* sqrt(NaN)=NaN, sqrt(+inf)=+inf
					   sqrt(-inf)=sNaN */
	} 
    /* take care of zero */
	if(ix0<=0) {
	    if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
	    else if(ix0<0)
		return (x-x)/(x-x);		/* sqrt(-ve) = sNaN */
	}
    /* normalize x */
	m = (ix0>>20);
	if(m==0) {				/* subnormal x */
	    while(ix0==0) {
		m -= 21;
		ix0 |= (ix1>>11); ix1 <<= 21;
	    }
	    for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
	    m -= i-1;
	    ix0 |= (ix1>>(32-i));
	    ix1 <<= i;
	}
	m -= 1023;	/* unbias exponent */
	ix0 = (ix0&0x000fffff)|0x00100000;
	if(m&1){	/* odd m, double x to make it even */
	    ix0 += ix0 + ((ix1&sign)>>31);
	    ix1 += ix1;
	}
	m >>= 1;	/* m = [m/2] */

    /* generate sqrt(x) bit by bit */
	ix0 += ix0 + ((ix1&sign)>>31);
	ix1 += ix1;
	q = q1 = s0 = s1 = 0;	/* [q,q1] = sqrt(x) */
	r = 0x00200000;		/* r = moving bit from right to left */

	while(r!=0) {
	    t = s0+r; 
	    if(t<=ix0) { 
		s0   = t+r; 
		ix0 -= t; 
		q   += r; 
	    } 
	    ix0 += ix0 + ((ix1&sign)>>31);
	    ix1 += ix1;
	    r>>=1;
	}

	r = sign;
	while(r!=0) {
	    t1 = s1+r; 
	    t  = s0;
	    if((t<ix0)||((t==ix0)&&(t1<=ix1))) { 
		s1  = t1+r;
		if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
		ix0 -= t;
		if (ix1 < t1) ix0 -= 1;
		ix1 -= t1;
		q1  += r;
	    }
	    ix0 += ix0 + ((ix1&sign)>>31);
	    ix1 += ix1;
	    r>>=1;
	}

    /* use floating add to find out rounding direction */
	if((ix0|ix1)!=0) {
	    z = one-tiny; /* trigger inexact flag */
	    if (z>=one) {
	        z = one+tiny;
	        if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;}
		else if (z>one) {
		    if (q1==(u_int32_t)0xfffffffe) q+=1;
		    q1+=2; 
		} else
	            q1 += (q1&1);
	    }
	}
	ix0 = (q>>1)+0x3fe00000;
	ix1 =  q1>>1;
	if ((q&1)==1) ix1 |= sign;
	ix0 += (m <<20);
	INSERT_WORDS(z,ix0,ix1);
	return z;
}

/*
Other methods  (use floating-point arithmetic)
-------------
(This is a copy of a drafted paper by Prof W. Kahan 
and K.C. Ng, written in May, 1986)

	Two algorithms are given here to implement sqrt(x) 
	(IEEE double precision arithmetic) in software.
	Both supply sqrt(x) correctly rounded. The first algorithm (in
	Section A) uses newton iterations and involves four divisions.
	The second one uses reciproot iterations to avoid division, but
	requires more multiplications. Both algorithms need the ability
	to chop results of arithmetic operations instead of round them, 
	and the INEXACT flag to indicate when an arithmetic operation
	is executed exactly with no roundoff error, all part of the 
	standard (IEEE 754-1985). The ability to perform shift, add,
	subtract and logical AND operations upon 32-bit words is needed
	too, though not part of the standard.

A.  sqrt(x) by Newton Iteration

   (1)	Initial approximation

	Let x0 and x1 be the leading and the trailing 32-bit words of
	a floating point number x (in IEEE double format) respectively 

	    1    11		     52				  ...widths
	   ------------------------------------------------------
	x: |s|	  e     |	      f				|
	   ------------------------------------------------------
	      msb    lsb  msb				      lsb ...order

 
	     ------------------------  	     ------------------------
	x0:  |s|   e    |    f1     |	 x1: |          f2           |
	     ------------------------  	     ------------------------

	By performing shifts and subtracts on x0 and x1 (both regarded
	as integers), we obtain an 8-bit approximation of sqrt(x) as
	follows.

		k  := (x0>>1) + 0x1ff80000;
		y0 := k - T1[31&(k>>15)].	... y ~ sqrt(x) to 8 bits
	Here k is a 32-bit integer and T1[] is an integer array containing
	correction terms. Now magically the floating value of y (y's
	leading 32-bit word is y0, the value of its trailing word is 0)
	approximates sqrt(x) to almost 8-bit.

	Value of T1:
	static int T1[32]= {
	0,	1024,	3062,	5746,	9193,	13348,	18162,	23592,
	29598,	36145,	43202,	50740,	58733,	67158,	75992,	85215,
	83599,	71378,	60428,	50647,	41945,	34246,	27478,	21581,
	16499,	12183,	8588,	5674,	3403,	1742,	661,	130,};

    (2)	Iterative refinement

	Apply Heron's rule three times to y, we have y approximates 
	sqrt(x) to within 1 ulp (Unit in the Last Place):

		y := (y+x/y)/2		... almost 17 sig. bits
		y := (y+x/y)/2		... almost 35 sig. bits
		y := y-(y-x/y)/2	... within 1 ulp


	Remark 1.
	    Another way to improve y to within 1 ulp is:

		y := (y+x/y)		... almost 17 sig. bits to 2*sqrt(x)
		y := y - 0x00100006	... almost 18 sig. bits to sqrt(x)

				2
			    (x-y )*y
		y := y + 2* ----------	...within 1 ulp
			       2
			     3y  + x


	This formula has one division fewer than the one above; however,
	it requires more multiplications and additions. Also x must be
	scaled in advance to avoid spurious overflow in evaluating the
	expression 3y*y+x. Hence it is not recommended uless division
	is slow. If division is very slow, then one should use the 
	reciproot algorithm given in section B.

    (3) Final adjustment

	By twiddling y's last bit it is possible to force y to be 
	correctly rounded according to the prevailing rounding mode
	as follows. Let r and i be copies of the rounding mode and
	inexact flag before entering the square root program. Also we
	use the expression y+-ulp for the next representable floating
	numbers (up and down) of y. Note that y+-ulp = either fixed
	point y+-1, or multiply y by nextafter(1,+-inf) in chopped
	mode.

		I := FALSE;	... reset INEXACT flag I
		R := RZ;	... set rounding mode to round-toward-zero
		z := x/y;	... chopped quotient, possibly inexact
		If(not I) then {	... if the quotient is exact
		    if(z=y) {
		        I := i;	 ... restore inexact flag
		        R := r;  ... restore rounded mode
		        return sqrt(x):=y.
		    } else {
			z := z - ulp;	... special rounding
		    }
		}
		i := TRUE;		... sqrt(x) is inexact
		If (r=RN) then z=z+ulp	... rounded-to-nearest
		If (r=RP) then {	... round-toward-+inf
		    y = y+ulp; z=z+ulp;
		}
		y := y+z;		... chopped sum
		y0:=y0-0x00100000;	... y := y/2 is correctly rounded.
	        I := i;	 		... restore inexact flag
	        R := r;  		... restore rounded mode
	        return sqrt(x):=y.
		    
    (4)	Special cases

	Square root of +inf, +-0, or NaN is itself;
	Square root of a negative number is NaN with invalid signal.


B.  sqrt(x) by Reciproot Iteration

   (1)	Initial approximation

	Let x0 and x1 be the leading and the trailing 32-bit words of
	a floating point number x (in IEEE double format) respectively
	(see section A). By performing shifs and subtracts on x0 and y0,
	we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.

	    k := 0x5fe80000 - (x0>>1);
	    y0:= k - T2[63&(k>>14)].	... y ~ 1/sqrt(x) to 7.8 bits

	Here k is a 32-bit integer and T2[] is an integer array 
	containing correction terms. Now magically the floating
	value of y (y's leading 32-bit word is y0, the value of
	its trailing word y1 is set to zero) approximates 1/sqrt(x)
	to almost 7.8-bit.

	Value of T2:
	static int T2[64]= {
	0x1500,	0x2ef8,	0x4d67,	0x6b02,	0x87be,	0xa395,	0xbe7a,	0xd866,
	0xf14a,	0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
	0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
	0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
	0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
	0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
	0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
	0x1527f,0x1334a,0x11051,0xe951,	0xbe01,	0x8e0d,	0x5924,	0x1edd,};

    (2)	Iterative refinement

	Apply Reciproot iteration three times to y and multiply the
	result by x to get an approximation z that matches sqrt(x)
	to about 1 ulp. To be exact, we will have 
		-1ulp < sqrt(x)-z<1.0625ulp.
	
	... set rounding mode to Round-to-nearest
	   y := y*(1.5-0.5*x*y*y)	... almost 15 sig. bits to 1/sqrt(x)
	   y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
	... special arrangement for better accuracy
	   z := x*y			... 29 bits to sqrt(x), with z*y<1
	   z := z + 0.5*z*(1-z*y)	... about 1 ulp to sqrt(x)

	Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
	(a) the term z*y in the final iteration is always less than 1; 
	(b) the error in the final result is biased upward so that
		-1 ulp < sqrt(x) - z < 1.0625 ulp
	    instead of |sqrt(x)-z|<1.03125ulp.

    (3)	Final adjustment

	By twiddling y's last bit it is possible to force y to be 
	correctly rounded according to the prevailing rounding mode
	as follows. Let r and i be copies of the rounding mode and
	inexact flag before entering the square root program. Also we
	use the expression y+-ulp for the next representable floating
	numbers (up and down) of y. Note that y+-ulp = either fixed
	point y+-1, or multiply y by nextafter(1,+-inf) in chopped
	mode.

	R := RZ;		... set rounding mode to round-toward-zero
	switch(r) {
	    case RN:		... round-to-nearest
	       if(x<= z*(z-ulp)...chopped) z = z - ulp; else
	       if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
	       break;
	    case RZ:case RM:	... round-to-zero or round-to--inf
	       R:=RP;		... reset rounding mod to round-to-+inf
	       if(x<z*z ... rounded up) z = z - ulp; else
	       if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
	       break;
	    case RP:		... round-to-+inf
	       if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
	       if(x>z*z ...chopped) z = z+ulp;
	       break;
	}

	Remark 3. The above comparisons can be done in fixed point. For
	example, to compare x and w=z*z chopped, it suffices to compare
	x1 and w1 (the trailing parts of x and w), regarding them as
	two's complement integers.

	...Is z an exact square root?
	To determine whether z is an exact square root of x, let z1 be the
	trailing part of z, and also let x0 and x1 be the leading and
	trailing parts of x.

	If ((z1&0x03ffffff)!=0)	... not exact if trailing 26 bits of z!=0
	    I := 1;		... Raise Inexact flag: z is not exact
	else {
	    j := 1 - [(x0>>20)&1]	... j = logb(x) mod 2
	    k := z1 >> 26;		... get z's 25-th and 26-th 
					    fraction bits
	    I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
	}
	R:= r		... restore rounded mode
	return sqrt(x):=z.

	If multiplication is cheaper then the foregoing red tape, the 
	Inexact flag can be evaluated by

	    I := i;
	    I := (z*z!=x) or I.

	Note that z*z can overwrite I; this value must be sensed if it is 
	True.

	Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
	zero.

		    --------------------
		z1: |        f2        | 
		    --------------------
		bit 31		   bit 0

	Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
	or even of logb(x) have the following relations:

	-------------------------------------------------
	bit 27,26 of z1		bit 1,0 of x1	logb(x)
	-------------------------------------------------
	00			00		odd and even
	01			01		even
	10			10		odd
	10			00		even
	11			01		even
	-------------------------------------------------

    (4)	Special cases (see (4) of Section A).	
 
 */
 
