0

There are multiple ways to find out the same and I tried using bitwise operation as -

if(((n<<3) - n)%7 == 0 ) {
    print "divide by 7";
}

Is there any other more efficient way?

As we can find if number is multiple of 3 using below algorithm -

If difference between count of odd set bits (Bits set at odd positions) and even set bits is multiple of 3 then so is the number.

Can we generalize the above algorithm for other numbers too?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
CodeQuestor
  • 881
  • 1
  • 11
  • 25
  • 1
    [Related](http://stackoverflow.com/questions/15262472/integer-division-by-7). – geometrian Aug 07 '15 at 04:30
  • Division is fast on a modern processor. I doubt you can beat hardware division unless you're programming for the GBA or something. – Antimony Aug 07 '15 at 04:31
  • 4
    What's wrong with `if (X % 7)==0` ? – Paul Aug 07 '15 at 04:32
  • 1
    In general a number is divisible by `n` if the sum of its digits in base `n+1` is divisible by `n`. So you can use the octal system in your case (groups of 3 bits) thats why it works. – hroptatyr Aug 07 '15 at 04:34
  • You can skip one substraction by using `if(n%7 == 0)`... – bytestorm Aug 07 '15 at 04:37
  • I am considering that i use same hardware for multiple implementation, so which one will be faster? As using bitwise is always faster, so modulo is going to be slower than bitwise operator. – CodeQuestor Aug 07 '15 at 04:49
  • @CodeQuestor It is not obvious that bitwise is faster. A hardware divide or modulo happens in the cpu, without reading additional instructions. doing loops, summing in some temporary register, etc. – Paul Aug 07 '15 at 05:00
  • 1
    I'm puzzled. Your code `if ((n << 3) - n) % 7 == 0)` is equivalent to `if ((7 * n) % 7 == 0)`, which is trivially true for all values of `n`. Who's confused — me or you? My compiler agrees with me; maybe I've brainwashed it to my way of thinking? – Jonathan Leffler Aug 07 '15 at 05:06
  • "As using bitwise is always faster" Are you sure that's true? Have you compared the performance for your algorithm for testing if numbers are divisible by 3? – bames53 Aug 07 '15 at 05:19
  • Possible duplicate of [How to check for division by 7 for big number in C++?](https://stackoverflow.com/questions/1550770/how-to-check-for-division-by-7-for-big-number-in-c) – phuclv Aug 07 '18 at 11:27

2 Answers2

5

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.

Paul
  • 26,170
  • 12
  • 85
  • 119
2

I think if(n%7 == 0) is more efficient way to check divisibility by 7.
But if you are dealing with large numbers and can't directly do modulus operation then this might help:

  1. A number of the form 10x + y is divisible by 7 if and only if x − 2y is divisible by 7. In other words, subtract twice the last digit from the number formed by the remaining digits. Continue to do this until a number known to be divisible by 7 is obtained. The original number is divisible by 7 if and only if the number obtained using this procedure is divisible by 7.
    For example, the number 371: 37 − (2×1) = 37 − 2 = 35; 3 − (2 × 5) = 3 − 10 = −7; thus, since −7is divisible by 7, 371 is divisible by 7.
  2. Another method is multiplication by 3. A number of the form 10x + y has the same remainder when divided by 7 as 3x + y. One must multiply the leftmost digit of the original number by 3, add the next digit, take the remainder when divided by 7, and continue from the beginning: multiply by 3, add the next digit, etc.
    For example, the number 371: 3×3 + 7 = 16 remainder 2, and 2×3 + 1 = 7.
    This method can be used to find the remainder of division by 7.
    P.S: reference
Milan Patel
  • 422
  • 4
  • 12