if((x & 4294967295LL) == 0) x >>= 32; if((x & 65535) == 0) x >>= 16; if((x & 255) == 0) x >>= 8; if((x & 15) == 0) x >>= 4; if((x & 3) == 0) x >>= 2;
if((x & 7) != 1) returnfalse;
int64 r, t, z; r = start[(x >> 3) & 1023]; do { z = x - r * r; if( z == 0 ) returntrue; if( z < 0 ) returnfalse; t = z & (-z); r += (z & t) >> 1; if( r > (t >> 1) ) r = t - r; } while( t <= (1LL << 33) );
returnfalse; }
首先进行快速过滤,排除负数和一些明显不是完全平方数的情况。
然后计算输入数对255取模的结果,并通过bad255数组进行判断。
接着使用二进制搜索去除输入数中2的幂次方。
最后,使用类似于Hensel引理的方法计算平方根,并进行判断。
核心代码
以下是一个综合多种优化方法的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicclassSquareRootChecker { long goodMask; { for (int i=0; i<64; ++i) goodMask |= Long.MIN_VALUE >>> (i*i); }
publicbooleanisSquare(long x) { if (goodMask << x >= 0) returnfalse; finalintnumberOfTrailingZeros= Long.numberOfTrailingZeros(x); if ((numberOfTrailingZeros & 1) != 0) returnfalse; x >>= numberOfTrailingZeros; if ((x&7) != 1 | x <= 0) return x == 0; finallongtst= (long) Math.sqrt(x); return tst * tst == x; } }