// sqrt using Newton's method, originally from w06 and w09 notes from class // using frexp and linear approximation // #include #include #include double mysqrt( double a) { if( a <= 0) return 0; double f; int e; f = frexp(a,&e); // a = f*pow(2,e), 0.5 <= f < 1.0 printf( "f = %g, e = %i\n", f, e); // debug // if e is odd, multiply f by 2 and subtract 1 from e to make e even // then use Newton to get x = square-root of f, then answer is ldexp(x,e/2) // if( abs(e) % 2 == 1 ) { // or: (e/2)*2 != e, or: e & 1 == 1 f *= 2; --e; printf( "f = %g, e = %i\n", f, e); // debug } // linear approximation for initial estimate // double prev, x = 0.75 + (1.414-0.707)/(2.0-0.5)*(f-0.5); // 0.5 <= f < 2.0 for( int count = 0; count < 50; ++count) { prev = x; // save copy of x x = (x + f/x)/2; // update x printf( "x = %.18g\n", x); //debug if( x == prev) break; // converged } return ldexp(x,e/2); } int main( void) { double a = 2; scanf( "%lf", &a); double x = mysqrt(a); double y = sqrt(a); printf( "a = %.18g\n", a); printf( "x = %.18g\n", x); printf( "y = %.18g\n", y); printf( "d = %.18g\n", x - y); return 0; }