package oebb; /** * A faster replacement for (int)(java.lang.Math.sqrt(x)). Completely accurate for x < 2147483648 (i.e. 2^31)... */ public class IMath { /** * Mark Borgerding's algorithm... * Not terribly speedy... * * no round => error 0.5 */ /** breaks for val >= 32768*32768 compare should be (guess*guess - val > 0) ??? static int mborg_isqrt(int val) { int guess=0; int bit = 1 << 15; do { guess ^= bit; // check to see if we can set this bit without going over sqrt(val)... if (guess * guess > val ) guess ^= bit; // it was too much, unset the bit... } while ((bit >>= 1) != 0); return guess; } */ /** breaks for val >= 32768*32768 static int mborg_isqrt2(int val) { int g, g2, b, b2, gxb; g = 0; // guess g2 = 0; // guess^2 b = 1<<15; // bit b2 = 1<<31; // 2*bit^2 gxb = 1<<30; // bit*(2*guess+bit) do { if( g2+gxb <= val ) { // (guess+bit)^2 <= val? g ^= b; // guess += bit g2 += gxb; // (g+b)^2 = g^2+gxb gxb += b2; // b(2(g+b)+b) = b(2g+b)+b^2 } b >>>= 1; // bit >>= 1 b2 >>>= 2; // 2(b/2)^2 = 2b^2/4 gxb = (gxb-b2) >>> 1; // b(2g+b/2)/2 = (b(2g+b)-2b^2/4)/2 } while(b != 0); return g; } */ static int sqrt(int val) { int temp, g=0, b = 0x8000, bshft = 15; do { if (val >= (temp = (((g<<1)+b)<<bshft--))) { g += b; val -= temp; } } while ((b >>= 1) != 0); return g; } /* public static void main(String[] args) { for (int i=0; i>=0; ++i) { if ((i&0xfffff)==0) { System.out.println(i); } // int j = mborg_isqrt(i); // int k = mborg_isqrt2(i); int l = sqrt(i); int m = (int) (java.lang.Math.sqrt(i)); // if (j!=m || k!=m || l!=m) { if (l!=m) { // System.out.println(i+" "+j+" "+k+" "+l+" "+m); System.out.println(i+" "+l+" "+m); break; } } } */ }