public class SqrtDemo { public static void main(String[] args){ //System.out.println(ourSqrt1(75,8,9)); System.out.println(ourSqrt2(75,8)); System.out.println(getSinDeriv(1)); } // look for sqrt(x) between lower and upper bounds public static float ourSqrt1(float x, float lower, float upper){ if(lower*lower > x){ throw new IllegalArgumentException("lower is too large"); } else if (upper*upper < x){ throw new IllegalArgumentException("upper is too small"); } float mid = 0; while(true){ mid = (lower + upper)/2; // quit if cannot make any further improvement // because lower and upper are consecutive floats if(mid == lower|mid == upper){ break; } System.out.println(""+lower+" "+ upper+" "+ mid); float midsq = mid*mid; if(midsq < x){ //search to right lower = mid; } else if(midsq > x){//search to left upper = mid; } } return mid; } // this method converges much faster public static double ourSqrt2(double x, double init){ double s = init; while(true){ // think of s and xos as being two sides of a // rectangle whose area is s*xos = x // we want the rectangle to be "more square" // so we set the new x to their average double xos = x/s; double diff = Math.abs(xos - s); if(diff < 1e-14){ break; } s = (s + xos)/2; System.out.println("" + s + " " + diff); } return s; } // this illustrates cancellation public static double getSinDeriv(double x){ // suppose we have Math.sin but not cos double h = 1; double divDif = 0; for(int j=0;j<20;j++){ h = h/10; double d1 = Math.sin(x + h); double d2 = Math.sin(x); divDif = (d1 - d2)/h; System.out.println("" + d1 + d2 + divDif + " " + h); } System.out.println("right answer is"+ Math.cos(x)); return divDif; } }