| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 | /*							sqrtl.c * *	Square root, long double precision * * * * SYNOPSIS: * * long double x, y, sqrtl(); * * y = sqrtl( 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. * * Note, some arithmetic coprocessors such as the 8087 and * 68881 produce correctly rounded square roots, which this * routine will not. * * ACCURACY: * * *                      Relative error: * arithmetic   domain     # trials      peak         rms *    IEEE      0,10        30000       8.1e-20     3.1e-20 * * * ERROR MESSAGES: * *   message         condition      value returned * sqrt domain        x < 0            0.0 * *//*Cephes Math Library Release 2.2:  December, 1990Copyright 1984, 1990 by Stephen L. MoshierDirect inquiries to 30 Frost Street, Cambridge, MA 02140*/#include <math.h>#define SQRT2 1.4142135623730950488017E0L#ifdef ANSIPROTextern long double frexpl ( long double, int * );extern long double ldexpl ( long double, int );#elselong double frexpl(), ldexpl();#endiflong double sqrtl(x)long double x;{int e;long double z, w;#ifndef UNKshort *q;#endifif( x <= 0.0 )	{	if( x < 0.0 )		mtherr( "sqrtl", DOMAIN );	return( 0.0 );	}w = x;/* separate exponent and significand */#ifdef UNKz = frexpl( x, &e );#endif/* Note, frexp and ldexp are used in order to * handle denormal numbers properly. */#ifdef IBMPCz = frexpl( x, &e );q = (short *)&x; /* point to the exponent word */q += 4;/*e = ((*q >> 4) & 0x0fff) - 0x3fe;*q &= 0x000f;*q |= 0x3fe0;z = x;*/#endif#ifdef MIEEEz = frexpl( 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 linear approximation = 7.47e-3 *//*x = 0.4173075996388649989089L + 0.59016206709064458299663L * z;*//* quadratic approximation, relative error 6.45e-4 */x = ( -0.20440583154734771959904L  * z     + 0.89019407351052789754347L) * z     + 0.31356706742295303132394L;/* adjust for odd powers of 2 */if( (e & 1) != 0 )	x *= SQRT2;/* re-insert exponent */#ifdef UNKx = ldexpl( x, (e >> 1) );#endif#ifdef IBMPCx = ldexpl( x, (e >> 1) );/**q += ((e >>1) & 0x7ff) << 4;*q &= 077777;*/#endif#ifdef MIEEEx = ldexpl( x, (e >> 1) );/**q += ((e >>1) & 0x7ff) << 4;*q &= 077777;*/#endif/* Newton iterations: */#ifdef UNKx += w/x;x = ldexpl( x, -1 );	/* divide by 2 */x += w/x;x = ldexpl( x, -1 );x += w/x;x = ldexpl( x, -1 );#endif/* Note, assume the square root cannot be denormal, * so it is safe to use integer exponent operations here. */#ifdef IBMPCx += w/x;*q -= 1;x += w/x;*q -= 1;x += w/x;*q -= 1;#endif#ifdef MIEEEx += w/x;*q -= 1;x += w/x;*q -= 1;x += w/x;*q -= 1;#endifreturn(x);}
 |