1*37da2899SCharles.Forsyth /* 2*37da2899SCharles.Forsyth sqrt returns the square root of its floating 3*37da2899SCharles.Forsyth point argument. Newton's method. 4*37da2899SCharles.Forsyth 5*37da2899SCharles.Forsyth calls frexp 6*37da2899SCharles.Forsyth */ 7*37da2899SCharles.Forsyth 8*37da2899SCharles.Forsyth #include <lib9.h> 9*37da2899SCharles.Forsyth 10*37da2899SCharles.Forsyth double sqrt(double arg)11*37da2899SCharles.Forsythsqrt(double arg) 12*37da2899SCharles.Forsyth { 13*37da2899SCharles.Forsyth double x, temp; 14*37da2899SCharles.Forsyth int exp, i; 15*37da2899SCharles.Forsyth 16*37da2899SCharles.Forsyth if(arg <= 0) { 17*37da2899SCharles.Forsyth if(arg < 0) 18*37da2899SCharles.Forsyth return NaN(); 19*37da2899SCharles.Forsyth return 0; 20*37da2899SCharles.Forsyth } 21*37da2899SCharles.Forsyth if(isInf(arg, 1)) 22*37da2899SCharles.Forsyth return arg; 23*37da2899SCharles.Forsyth x = frexp(arg, &exp); 24*37da2899SCharles.Forsyth while(x < 0.5) { 25*37da2899SCharles.Forsyth x *= 2; 26*37da2899SCharles.Forsyth exp--; 27*37da2899SCharles.Forsyth } 28*37da2899SCharles.Forsyth /* 29*37da2899SCharles.Forsyth * NOTE 30*37da2899SCharles.Forsyth * this wont work on 1's comp 31*37da2899SCharles.Forsyth */ 32*37da2899SCharles.Forsyth if(exp & 1) { 33*37da2899SCharles.Forsyth x *= 2; 34*37da2899SCharles.Forsyth exp--; 35*37da2899SCharles.Forsyth } 36*37da2899SCharles.Forsyth temp = 0.5 * (1.0+x); 37*37da2899SCharles.Forsyth 38*37da2899SCharles.Forsyth while(exp > 60) { 39*37da2899SCharles.Forsyth temp *= (1L<<30); 40*37da2899SCharles.Forsyth exp -= 60; 41*37da2899SCharles.Forsyth } 42*37da2899SCharles.Forsyth while(exp < -60) { 43*37da2899SCharles.Forsyth temp /= (1L<<30); 44*37da2899SCharles.Forsyth exp += 60; 45*37da2899SCharles.Forsyth } 46*37da2899SCharles.Forsyth if(exp >= 0) 47*37da2899SCharles.Forsyth temp *= 1L << (exp/2); 48*37da2899SCharles.Forsyth else 49*37da2899SCharles.Forsyth temp /= 1L << (-exp/2); 50*37da2899SCharles.Forsyth for(i=0; i<=4; i++) 51*37da2899SCharles.Forsyth temp = 0.5*(temp + arg/temp); 52*37da2899SCharles.Forsyth return temp; 53*37da2899SCharles.Forsyth } 54