Perfect square

How do you write code to determine a perfect square for any integer? I understand Math.sqrt();Thanks
[114 byte] By [pacificwara] at [2007-10-1 4:19:28]
# 1

> How do you write code to determine a perfect square

> for any integer? I understand Math.sqrt();

>

> Thanks

It is in the series of the sum of odd numbers up to a given point

1 = 1

1+3 = 4

1+3+5 = 9

...

The sqrt is an int

And, I'm sure, other methods...

~Cheers

Adeodatusa at 2007-7-9 4:49:47 > top of Java-index,Other Topics,Algorithms...
# 2
http://id.mind.net/~zona/mmts/miscellaneousMath/perfectSquare/perfectSquare.htmlis what the phrase normally means, but what do you mean?
pm_kirkhama at 2007-7-9 4:49:47 > top of Java-index,Other Topics,Algorithms...
# 3

Here's is a binary search method

static boolean perfectSquare(int x){

int lo = 0;

int hi = 0xF7DE;

while(lo + 1 < hi){

int v = (lo+hi)/2;

if(v*v < x) lo = v; else hi = v;

}

return((lo*lo == x || hi*hi == x));

}

I leave it to you to explain why I use the number F7DE to start it off, and why this algorithm gives the correct answer for negative numbers (which are not perfect squares) and to also explain why the expression (lo+hi)/2 does not overflow when squared. And while you're at it why doesn't it end up in an infinite loop?

If you follow all that, you understand this algorithm and I need say no more. On the other hand you don't really need to understand any of that in order to use it.

But in that case, you might properly wonder whether I got any of this right. Did I use the right magic number, does it really work for the full range, and does it really terminate for all input, and is it anything like efficient?

marlin314a at 2007-7-9 4:49:47 > top of Java-index,Other Topics,Algorithms...
# 4

Glad you guys check me on these results.

You're absolutely right, the magic number should have been 0xB504. My hex is a little rusty and I typed the wrong number into my hex calculator.

I haven't gotten at thing right all day. (sigh!) So now the code is up there all wrong and people will cut and paste it. And soon it will be all over the internet, indexed on Google and no one will read this addendum.

Oh well. That's how bad memes get propagated.

This is why you should never trust the experts.

marlin314a at 2007-7-9 4:49:47 > top of Java-index,Other Topics,Algorithms...
# 5
"Beware of bugs in the above code. I have only proven it correct, not tested it" -- Knuth
YATArchivista at 2007-7-9 4:49:47 > top of Java-index,Other Topics,Algorithms...
# 6

Another method is using the bitpattern:

public static int sqrt (int i) {

// the bitwise method

if (i < 0) {

throw new IllegalArgumentException("i must be >= 0, i = " + i);

}

if (i == 0) {

return 0;

}

// find max power of 2 not greater than sqrt(i)

int n = 15;

int root = (1 << n);

int square = root * root;

while (square > i) {

n --;

root >>= 1;

square >>= 2;

}

if (verbose) {

System.out.println(i + " " + root + " " + square + " " + n + " " + Integer.toBinaryString(root));

}

// now switch bits until the result is found

for (n--; n>=0; n--) {

if (square == i) { break; }

if (square < i) {

int newRoot = root + (1 << n);

int newSquare = newRoot * newRoot;

if ((newSquare <= i) && (newSquare > 0)) { // may overflow

root = newRoot;

square = newSquare;

}

}

if (verbose) {

System.out.println(i + " " + root + " " + square + " " + n + " " + Integer.toBinaryString(root));

}

}

return root;

}

This scales better for any precision integers, though you would use

s_old = r^2

s_new = (r + d)^2

d = 2^n

(r + d)^2 = r^2 + 2rd + d^2 = s_old + r<<(n+1) + 1<<(2n)

as the bitshifts get faster than multiplication for many big int implementations (O(logN) rather than O((log(N))^2).

This is equivalent to bisection for integers, but the starting point is better, and less magic.

Pete

pm_kirkhama at 2007-7-9 4:49:47 > top of Java-index,Other Topics,Algorithms...
# 7

Here's an algorithm for finding squares in general.

PERFECT SQUARE SIEVE

To test if a number is a perfect square we make use of the fact that it must produce a quadratic residue for every prime. If it does not do this for a single prime it cannot be square.

Take a list of, say, 50 small primes. Call these P1, P2, P3, ...P50.

Assume n is not a perfect square.

Let n = q (mod p) for any prime. The chances that q is a quadratic residue of p is 1/2, since there are (p + 1)/2 quadratic residues (including zero) and (p - 1)/2 nonquadratic residues.

Let n = q (mod P1). The chances of q being a quadratic residue of P1 are 1/2.

Let n = q2 (mod P2). The chances of q2 being a quadratic residue of P2 are 1/2.

1/2 x 1/2 = 1/4.

Let n = q3 (mod P3). The chances of q3 being a quadratic residue of P3 are 1/2.

1/2 x 1/2 x 1/2 = 1/8.

Continue in this way to P50. The chances of a non-square n filtering through the entire sieve is only 1 in 250.

To proove that the chances that q is a quadratic residue is 1/2, consider p consecutive integers for any prime, p. These will be reduce to 0,1,2,...p - 1 modulo p (not necessarily in that order). There will be one integer congruent to zero and (p - 1)/2 congruent to q such that q is a quadratic residue and (p - 1)/2 congruent to r such that r is a nonquadratic residue. So the chances are 1/2 for any given integer.

If n = qi = 0 (mod Pi), Pi|n and it must be that n = 0 (mod Pi^2) if n is a square because each prime divisor of n must occur to an even power in its decomposition into factors. If this is not the case, n cannot be square and it can be rejected on this count alone.

scriptoHeada at 2007-7-9 4:49:47 > top of Java-index,Other Topics,Algorithms...