[seqfan] Re: Testing potential squares

Peter Munn techsubs at pearceneptune.co.uk
Fri Aug 24 14:08:39 CEST 2018


Hello Keith,

This thread has been a productive source of methods to help with resource
limits and this type of challenge.

Your particular challenge, if I have understood it, may be appropriate for
the following solution to be the fastest with the resources to hand.

Let L be a lower bound for the numbers being tested, and m be the number
of bits in floor(sqrt(L)). Generate all the squares in the range to be
tested, storing each square n (or its least m bits) in floor((n-L)/2^m)
position of a look-up list, the list elements having been initialised to
-1 for when there is no square within the interval it covers.

Best Regards,

Peter

On Tue, August 21, 2018 1:09 pm, Keith F. Lynch wrote:
> I recently wanted to test a large number of large numbers to see
> if they were squares.  I wanted to do so as quickly as possible.
> The odds of a positive integer around N being square are about
> 1/(2*sqrt(N)).  So if N is around a trillion (10^12), the odds
> are about 1 in 2 million.
>
> The obvious way to test is to take the square root.  But that's slow.
>
> To quickly rule out most non-squares, I created, just once, at the
> beginning of the program, a table of all quadratic residues mod 2^16
> (65536).  Then I tested every potential square by ANDing it with
> 2^16-1 (65535), and looking up the result in that table, both of which
> are very fast.  That rules out nearly 5/6 of all non-squares.  The
> proportions of quadratic residues modulo higher and higher powers of 2
> quickly approach 1/6.  (2^16 already gets 1/5.999268.  See A023105.)

[...]

> If I have one gigabyte to devote to the task, I can instead test my
> prospective square mod 7661478825, a larger record-setting odd number,
> which has about 1/233 residues.  That requires one bit per residue
> to get it to fit in one gigabyte.  If N is my prospective square mod
> 7661478825, I shift N right 3 bits to get the byte to look up in the
> table.  There will be about a 1/29 chance of a hit, i.e. at least one
> residue in the block of 8 containing the correct bit.  Only if there
> is a hit do I check the bit, which I do by ANDing N with 7, and using
> that as the index of which bit in that byte to look at.  So I've ruled
> out all but about 1/1400 non-squares.
>
> I can do better.  [...]

> I'm curious whether anyone can think of a faster way to test large
> numbers for squareness.




More information about the SeqFan mailing list