| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 | /*							sqrt.c * *	Square root * * * * SYNOPSIS: * * double x, y, sqrt(); * * y = sqrt( x ); * * * * DESCRIPTION: * * Returns the square root of x. * * Range reduction involves isolating the power of two of the * argument and using a polynomial approximation to obtain * a rough value for the square root.  Then Heron's iteration * is used three times to converge to an accurate value. * * * * ACCURACY: * * *                      Relative error: * arithmetic   domain     # trials      peak         rms *    DEC       0, 10       60000       2.1e-17     7.9e-18 *    IEEE      0,1.7e308   30000       1.7e-16     6.3e-17 * * * ERROR MESSAGES: * *   message         condition      value returned * sqrt domain        x < 0            0.0 * *//*Cephes Math Library Release 2.8:  June, 2000Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier*/#include <math.h>#ifdef ANSIPROTextern double frexp ( double, int * );extern double ldexp ( double, int );#elsedouble frexp(), ldexp();#endifextern double SQRT2;  /*  SQRT2 = 1.41421356237309504880 */double sqrt(x)double x;{int e;#ifndef UNKshort *q;#endifdouble z, w;if( x <= 0.0 )	{	if( x < 0.0 )		mtherr( "sqrt", DOMAIN );	return( 0.0 );	}w = x;/* separate exponent and significand */#ifdef UNKz = frexp( x, &e );#endif#ifdef DECq = (short *)&x;e = ((*q >> 7) & 0377) - 0200;*q &= 0177;*q |= 040000;z = x;#endif/* Note, frexp and ldexp are used in order to * handle denormal numbers properly. */#ifdef IBMPCz = frexp( x, &e );q = (short *)&x;q += 3;/*e = ((*q >> 4) & 0x0fff) - 0x3fe;*q &= 0x000f;*q |= 0x3fe0;z = x;*/#endif#ifdef MIEEEz = frexp( x, &e );q = (short *)&x;/*e = ((*q >> 4) & 0x0fff) - 0x3fe;*q &= 0x000f;*q |= 0x3fe0;z = x;*/#endif/* approximate square root of number between 0.5 and 1 * relative error of approximation = 7.47e-3 */x = 4.173075996388649989089E-1 + 5.9016206709064458299663E-1 * z;/* adjust for odd powers of 2 */if( (e & 1) != 0 )	x *= SQRT2;/* re-insert exponent */#ifdef UNKx = ldexp( x, (e >> 1) );#endif#ifdef DEC*q += ((e >> 1) & 0377) << 7;*q &= 077777;#endif#ifdef IBMPCx = ldexp( x, (e >> 1) );/**q += ((e >>1) & 0x7ff) << 4;*q &= 077777;*/#endif#ifdef MIEEEx = ldexp( x, (e >> 1) );/**q += ((e >>1) & 0x7ff) << 4;*q &= 077777;*/#endif/* Newton iterations: */#ifdef UNKx = 0.5*(x + w/x);x = 0.5*(x + w/x);x = 0.5*(x + w/x);#endif/* Note, assume the square root cannot be denormal, * so it is safe to use integer exponent operations here. */#ifdef DECx += w/x;*q -= 0200;x += w/x;*q -= 0200;x += w/x;*q -= 0200;#endif#ifdef IBMPCx += w/x;*q -= 0x10;x += w/x;*q -= 0x10;x += w/x;*q -= 0x10;#endif#ifdef MIEEEx += w/x;*q -= 0x10;x += w/x;*q -= 0x10;x += w/x;*q -= 0x10;#endifreturn(x);}
 |