I\'m looking for the fastest way to determine if a long
value is a perfect square (i.e. its square root is another integer):
It's been pointed out that the last d
digits of a perfect square can only take on certain values. The last d
digits (in base b
) of a number n
is the same as the remainder when n
is divided by b
d
, ie. in C notation n % pow(b, d)
.
This can be generalized to any modulus m
, ie. n % m
can be used to rule out some percentage of numbers from being perfect squares. The modulus you are currently using is 64, which allows 12, ie. 19% of remainders, as possible squares. With a little coding I found the modulus 110880, which allows only 2016, ie. 1.8% of remainders as possible squares. So depending on the cost of a modulus operation (ie. division) and a table lookup versus a square root on your machine, using this modulus might be faster.
By the way if Java has a way to store a packed array of bits for the lookup table, don't use it. 110880 32-bit words is not much RAM these days and fetching a machine word is going to be faster than fetching a single bit.