Live data from Hacker News

Testing for Divisibility by 19

blog.plover.com

11–20 of 42 posts

Re: Testing for Divisibility by 19

#11

> The result will be a smaller number which has the same mod-19 residue. It seems to me that the procedure works only for numbers divisible by 19. If it's not divisible, the residue may change. Try 20 for example.

I wonder if it doubles the residue. 20 -> 2, 21 -> 4. But 18 -> 17. And 10 -> 1. So no.

Re: Testing for Divisibility by 19

#12

can this kind of trick be implemented in a compiler for any benefit?

Not really, first of all because the tricks are in base 10 But you can make tricks for base 16 or 256 if you really need to check for a certain divisibility multiple times

> But you can make tricks for base 16 or 256 if you really need to check for a certain divisibility multiple times

You don't need any tricks in that case since a simple bit mask (bit-wise AND) will do the trick then.

Re: Testing for Divisibility by 19

#13

can this kind of trick be implemented in a compiler for any benefit?

Other similar compiler optimizations do exist, for, for example, reducing a multiplication by a constant into a series of additions and bit-shifts. It might be possible to reduce divisibility checks for constants in binary at compile time in a similar manner, but no existing work comes to mind.

There's a way for odd divisors, since they have a multiplicative inverse mod 2^n.

For example, the inverse of 3 modulo 2^32 is 0xAAAAAAAB. If you multiply an unsigned number x by 0xAAAAAAAB, the result is less than or equal to 0xFFFFFFFF/3 if and only x is divisible by 3.

Of course this is only possible for non-bignum computations.

But there are other tricks for bignums, for example the number of even set bits in a multiple of three is equal to the number of odd set bits, because 4*n+k = n+k (mod 3) and the property is true for 0 and 3 but not 1 and 2.

Re: Testing for Divisibility by 19

#15
post #6

can this kind of trick be implemented in a compiler for any benefit?

I don't think so. It's not really more efficient than long division, with the same number of operations for each digit of the big number. Most of the improvement for humans comes from the fact that you get to deal with smaller numbers (0-9) for a section of those operations than with the bigger range 0-19, but the computer generally doesn't find it easier to multiply by one 64-bit number than another. In any case, in…

Yeah if dividing by 19 became a common thing for programs to do, companies like intel or ARMvidia would add an optimized instruction for it.

Re: Testing for Divisibility by 19

#16
post #11

> The result will be a smaller number which has the same mod-19 residue. It seems to me that the procedure works only for numbers divisible by 19. If it's not divisible, the residue may change. Try 20 for example.

I wonder if it doubles the residue. 20 -> 2, 21 -> 4. But 18 -> 17. And 10 -> 1. So no.

Well, it does double the residue:

20 * 2 === 40 === 2 (mod 19)

21 * 2 === 42 === 4 (mod 19)

18 * 2 === 36 === 17 (mod 19), equivalently -1 * 2 === -2 === 17 (mod 19)

10 * 2 === 20 === 1 (mod 19), equivalently -9 * 2 === -18 === 1 (mod 19)

Re: Testing for Divisibility by 19

#17
post #11

> The result will be a smaller number which has the same mod-19 residue. It seems to me that the procedure works only for numbers divisible by 19. If it's not divisible, the residue may change. Try 20 for example.

I wonder if it doubles the residue. 20 -> 2, 21 -> 4. But 18 -> 17. And 10 -> 1. So no.

It does double the residue, but modulo 19. 2 * 18 = 36 = 17 (mod 19) and 2 * 10 = 20 = 1 (mod 19). The reason is that the method consists essentially of two steps. (1) Subtract a suitable multiple of 19 to make the number a multiple of 10. (2) Divide by 10. And dividing by 10 is the same as multiplying by 2, since 2 * 10 = 20 = 1 (mod 19).

Re: Testing for Divisibility by 19

#19
post #12

Earlier quoted context omitted.

Not really, first of all because the tricks are in base 10 But you can make tricks for base 16 or 256 if you really need to check for a certain divisibility multiple times

> But you can make tricks for base 16 or 256 if you really need to check for a certain divisibility multiple times You don't need any tricks in that case since a simple bit mask (bit-wise AND) will do the trick then.

No bitmask will give you divisibility by 3 in base 16

In this case (division by 3 in mod 16) is the same as base 10: if the sum of digits is divisible by 3 then it is divisible (and the "extra digits" are 'c' and 'f')

Examples:

0x3c (60) -> sum = 0xf (divisible)

0x2d (45) -> sum = 0xf (divisible)

Re: Testing for Divisibility by 19

#20
post #12

Earlier quoted context omitted.

Not really, first of all because the tricks are in base 10 But you can make tricks for base 16 or 256 if you really need to check for a certain divisibility multiple times

> But you can make tricks for base 16 or 256 if you really need to check for a certain divisibility multiple times You don't need any tricks in that case since a simple bit mask (bit-wise AND) will do the trick then.

I may be misunderstanding - a bit mask only tells you if something is divisible by 16 or 256 (or any other power of 2)

I think he's saying in base 16 you can make a trick to check divisibility by e.g. 15 in the same way you can check divisibility by 9 in base 10.

So is 0xE1 (225) divisible by 0xF (15)?

0xE + 0x1 = 0xF, so yes.

Post reply on HN