I was asked a question today how can we check whether a number N is divisible by 7 using bitwise operators. Then I was asked to do the same for 3.
Initial Approach (wrong approach):
To observe bit patterns
for e.g. 3 = 00000011, 6 = 00000110, 9 = 00001001 and so on...
I thought that all the binary 1's will conform to either 11 or 1001. BUT this was wrong, it failed for 81.
The Final Approach (courtesy google):
After a bit of googling I found an approach which has to do with modulo arithmetic in Numbers Theory.
(3)10 = (11)2 Note: I will use this notation whenever needed to avoid confusion
The algorithm:
1 - Take the Binary of the number
2 - Divide the entire sequence of bits into pairs of bits
3 - Take the sum of all these pairs
4 - If the sum is greater than three then repeat Steps 1, 2, 3 for this sum
5 - If sum is 0 or 3 then number is divisible by three else not. Moreover this sum will have the remainder.
For e.g. let us take (assume 8 bits for simplicity)
First Iteration:(40)10 = (00101000)2 = 00 10 10 00 ==> Sum = (4)10(41)10 = (00101001)2 = 00 10 10 01 ==> Sum = (5)10(42)10 = (00101010)2 = 00 10 10 10 ==> Sum = (6)10Second Iteration:(4)10 = (00000100)2 = 00 00 01 00 ==> Sum = (1)10 ==> 40%3 = 1(5)10 = (00000101)2 = 00 00 01 01 ==> Sum = (2)10 ==> 41%3 = 2(6)10 = (00000110)2 = 00 00 01 10 ==> Sum = (3)10 ==> 42%3 = 0Thus 42 is divisible
Similar approach is for checking divisibility with 7. Only this time instead this time taking pairs of consecutive bits we take triplets because (7)10 = (111)2
Consider a sample code for N % 7 using the above approach.
unsigned int calcRemainder(unsigned int n){unsigned int sum = 0;while(1){sum = 0; // Correction done as mentioned by Jitendrawhile(n){sum += n&7;n = n >> 3; // seven is 3 1s (ones) so shift by three}if(sum>7)n = sum;else if(sum==7)return 0;elsereturn sum;}}
The code looks similar to what we do for checking divisibility with 3 or 9 in decimal number system. We take the sum of all the digits recursively till we get a single either divisible or not divisible by 3 or 9.
The only limitation that I could observe was that this technique works for numbers like which of the form 2^n - 1 such as 3, 7, 15. (I havent tried it for other numbers anyways :P )
The link I referred to is
http://stackoverflow.com/questions/48053/is-there-an-alternative-to-using-modulus-in-c-c
http://stackoverflow.com/questions/48053/is-there-an-alternative-to-using-modulus-in-c-c
However I wasn't able to deduce this mathematically (I'm not a maths guy). So If any of you Mathos can give me mathematical proof and may be extend this algorithm for other numbers as well, kindly add them as a comment, or mail mel. I will surely update the blog.
it is nice one...............
ReplyDeletegood luck good going.........
Very good logic
ReplyDeleteone correction to be done
In your code you have declare sum outside the outer loop while loop.
Inside while(1) loop we have to again make the sum=0 to make the run properly on the case if sum>7
:)