From b3503c17b0dddcdad34fdda9df2e85c584af31bc Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Tue, 24 Jul 2018 19:01:48 -0500 Subject: [PATCH] Simplify perfect-square testing loop There's no need for the `bits` variable here. The number of loop iterations can be cut in half by repeatedly shifting right by 2 so long as the last 2 bits are zeroes. If there were in fact an odd number of trailing zero bits in `q0`, that will leave `tmp` with a last bit of 0, and so it won't pass the later `(tmp & 7) == 1` test. If there were an even number of trailing zero bits, `tmp` is left the same as before the change, and again the only real thing left to test is whether `(tmp & 7) == 1`. Caution: I didn't test or even compile this code! I was just browsing this on the web, and am using the web UI to edit. I've used the same trick in other projects, and am sure it's sound (give it a little thought - it's obvious ;-) ). Apologies in advance for any typos. --- common/smallfact/squfof.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/common/smallfact/squfof.c b/common/smallfact/squfof.c index ce6d161..413d82f 100644 --- a/common/smallfact/squfof.c +++ b/common/smallfact/squfof.c @@ -70,7 +70,7 @@ uint32 squfof_one_cycle(squfof_data_t *data, uint32 mult_idx, uint64 scaledn; for (i = 0; i < num_iter; i++) { - uint32 q, bits, tmp; + uint32 q, tmp; /* compute (sqrtn+p1)/q1; since this is unity more than half the time, special case the @@ -113,18 +113,15 @@ uint32 squfof_one_cycle(squfof_data_t *data, uint32 mult_idx, /* if q0 is a perfect square, then the factorization has probably succeeded. Most of the squareness tests out there require multiple divisions and - complicated loops. We can approximate these tests - by doing two things: testing that the number of - trailing zeros in q0 is even, and then testing - if q0 shifted right this many places is 1 mod 8. */ + complicated loops. We approximate these tests by + ensuring that the last 3 bits are 001 after + dividing (shifting) out all factors of 4. */ - bits = 0; tmp = q0; - while(!(tmp & 1)) { - bits++; - tmp >>= 1; + while(!(tmp & 3)) { + tmp >>= 2; } - if (!(bits & 1) && ((tmp & 7) == 1)) { + if ((tmp & 7) == 1) { /* q0 is probably a perfect square. Take the square root by cheating */