So if your number is representable by a hardware-supported integer, and the hardware has a division or modulo operations, you should just use those. It is simpler, and probably faster than anything you will write. To even compete with the hardware, you must use an assembler and use other faster instructions better than the hardware manufacturers did, and without the advantage of undocumented tricks they could use but you can not.
Where this question becomes interesting is where arbitrarily large integers are involved. Modulo has some tricks for that. For instance, I can tell you that 100000000010000010000 is divisible by 3, even though my brain is a horribly slow math processor compared to a computer, because of these properties of the %
modulo operator:
(a+b+c) % d = ( (a%d) + (b%d) + (c%d) ) %d
(n*a) % d = ( (a%d) + (a%d) + (a%d) +... (n times) ) %d = (n*(a%d)) %d
Now note that:
- 10 % 3 = 1
- 100 % 3 = (10 * (10%3)) % 3 = 10%3 = 1
- 1000 % 3 = (10 * (100%3)) %3 = 1
etc...
So that to tell if a base-10 number is divisible by 3, we simply sum the digits and see if the sum is divisible by 3
Now using the same trick with a large binary number expressed in octal or base-8 (also pointed out by @hropyatr above in comments), and using divisibility by 7, we have the special case:
8 % 7 = 1
and from that we can deduce that:
(8**N) % 7 = (8 * (8 * ( ... *( 8 * (8%7) % 7 ) % 7 ) ... %7 = 1
so that to "quickly" test divisibility by 7 of an arbitrarily large octal number, all we need to do is add up its octal base-8 digits and try dividing that by 7.
Finally, the bad news.
The code posted:
if ( (n<<3 - n) % 7 ==0 ) ...
is not a good test for divisibility by 7.
because it is always yields true
for any n
(as pointed out by @Johnathan Leffler)
n<<3 is multiplication by 8, and will equal 8n
So for instance 6 is not divisible by 7,
but 6<<3 = 48
and 48 - 6 = 42
, which is divisible by 7
.
If you meant right shift if ( (n>>3 - n ) % 7 == 0 )
that doesn't work either. Test it with 49, 49//8
is 6
, 6-49
is -43
and although 49 is divisible by 7, -43
is not.
The simplest test, if (n % 7 ) == 0
is your best shot until n overflows hardware, and at that point you can find a routine to represent n in octal, and sum the octal digits modulo 7.