|
#includedouble
sqrt(x)
double x;
{
double og, ng;
short niter;
int expon;if(x <= 0.0)
return 0.0;
og = x;
if(og < 1.0)
og = 1.0/og;
og = frexp(og, &expon);
og = ldexp(og, expon/2); /* make an educated guess */
if(x < 1.0)
og = 1.0/og;
niter = 20;
do {
ng = (x/og + og)/2.0;
if(ng == og)
break;
og = ng;
} while(--niter);
return og;
}
/* Frexp/ldexp in C/*
* $Header: /hitech/cvsroot/nz/libc/common/frexp.c,v 1.4 2003/07/25 01:23:21 lucky Exp $
*
* $Log: frexp.c,v $
* Revision 1.4 2003/07/25 01:23:21 lucky
* Changed MSP's macro to __MSP430C__
*
* Revision 1.3 2002/12/19 03:49:25 clyde
* Added MSP430 to frexp.c
*
* Revision 1.2 1995/10/18 15:36:10 clyde
* 64 bit mods
*
* Revision 1.1 95/10/08 22:00:28 clyde
* Initial revision
*
* Revision 1.1 95/10/08 21:59:28 clyde
* Initial revision
*
*/#if defined(_XA_) || defined(i8096) || defined(i8086) || defined(__MSP430C__)
#define LITTLE_ENDIAN
#endif#if sizeof(double) == 4
union both
{
struct flt
{
#if z80
#define EXCESS 64
unsigned char mant[2];
unsigned hmant:8;
unsigned exp:7;
unsigned sign:1;
#else
#define EXCESS 126
#ifdef LITTLE_ENDIAN
unsigned char mant[2];
unsigned hmant:7;
unsigned exp:8;
unsigned sign:1;
#else
unsigned sign:1;
unsigned exp:8;
unsigned hmant:7;
unsigned char mant[2];
#endif
#endif
} flt;
double fl;
};#else
#define EXCESS 1022
union both
{
struct flt
{
#ifdef LITTLE_ENDIAN
unsigned char mant[6];
unsigned hmant:4;
unsigned exp:11;
unsigned sign:1;
#else
unsigned sign:1;
unsigned exp:11;
unsigned hmant:4;
unsigned char mant[6];
#endif
} flt;
double fl;
};
#endifdouble
frexp(union both value, int * eptr)
{
*eptr = value.flt.exp - EXCESS;
value.flt.exp = EXCESS;
return value.fl;
}double
ldexp(union both value, int newexp)
{
value.flt.exp += newexp;
return value.fl;
}
E-mail: info@telesys.ru