Logic to check the number is divisible by 3 or not?

后端 未结 10 1410
清歌不尽
清歌不尽 2021-01-14 16:31

without using %, / or * , I have to find the no. is divisible by 3 or not?

it might be an interview question.

Thanks.

相关标签:
10条回答
  • 2021-01-14 17:03

    There are various ways. The simplest is pretty obvious:

    int isdivby3(int n) {
        if (n < 0) n = -n;
    
        while (n > 0) n -= 3;
    
        return n == 0;
    }
    

    But we can improve that. Any number can be represented like this: ("," means range inclusive):

    Base2 (AKA binary)
    (0,1) + 2*(0,1) + 4*(0,1)
    
    Base4
    (0,3) + 4*(0,3) + 16*(0,3)
    
    BaseN
    (0,N-1) + N*(0,N-1) + N*N*(0,N-1)
    

    Now the trick is, a number x is divisible by n-1 if and only if the digitsum of x in base n is divisible by n-1. This trick is well-known for 9:

    1926 = 6 + 2*10 + 9*100 + 1*1000
    6+2+9+1 = 8 + 1*10
    8+1 = 9 thus 1926 is divisible by 9
    

    Now we can apply that for 3 too in base4. And were lucky since 4 is a power of 2 we can do binary bitwise operations. I use the notation number(base).

    27(10) = 123(4)
    Digitsum
    12(4)
    Digitsum again
    3(4) = Divisible!
    

    Now let's translate that to C:

    int div3(int n) {
        if (n < 0) n = -n;
        else if (n == 0) return 1;
    
        while (n > 3) {
            int d = 0;
    
            while (n > 0) {
                d += n & 3;
                n >>= 2;
            }
    
            n = d;
        }
    
        return n == 3;
    }
    

    Blazing fast.

    0 讨论(0)
  • 2021-01-14 17:03

    To print a count sequence which is divisible by 3 without division or modulus operator.

    Notice the count sequence:

    00: 00(00)
    01: 0001
    02: 0010
    03: 00(11)
    04: 0100
    05: 0101
    06: 01(10)
    07: 0111
    08: 1000
    09: 10(01)
    10: 1010
    11: 1011
    12: 11(00)
    13: 1101
    14: 1110
    15: 11(11)
    16: 10000
    17: 10001
    18: 100(10)
    19: 10011
    20: 10100
    21: 101(01)
    

    Note that the last two bits of those numbers which are divisible by three (shown in brackets) are cycling through {00, 11, 10, 01} . What we need to check is if the last two bits of the count sequence has these bits in a sequence.

    First we start matching with mask = 00 and loop while the first number is not encountered with the lower two bits 00. When a match is found we then do (mask + 03) & 0x03 which gets us the next mask in the set. And we continue to match the last two bits of the next count with 11. Which can be done by ((count & 3) == mask)

    The code is

    #include <stdio.h>
    
    int main (void)
    {
      int i=0;
      unsigned int mask = 0x00;
    
      for (i=0; i<100;i++)
      {
        if ((i&0x03) == mask)
        {
          printf ("\n%d", i);
          mask = (mask + 3) & 0x03;
        }
      }
      printf ("\n");
      return 0;
    }
    

    This is not a general one. Best is to use the solution which @nightcracker have suggested

    Also if you really want to implement the division operation i without using the divide operations. I would tell you to have a look at the Non-Restoring Division Algorithm, this can be done in program with a lot of bit manipulations with bitwise operators. Here are some links and references for it.

    Wikipedia Link

    Here is a demo from UMass

    Also have a look at Computer Organization by Carl Hamacher, Zvonko Vranesic, Safwat Zaky

    0 讨论(0)
  • 2021-01-14 17:03

    Suppose n is the number in question and it is non-negative.

    If n is 0 it is divisible by 3; otherwise n = (2^p)*(2*n1+1) and n is divisible by 3 iff 2*n1+1 is, iff there is a k>=0 with 2*n1+1 = 3*(2*k+1) iff n1 = 3*k+1 iff n1=1 or n1> 1 and n1-1 is divisible by 3. So:

    int ism3( int n)
    {   for(;n;)
        {    while( !(n & 1)) n >>= 1;
             n >>= 1;
             if ( n == 0) return 0;
             n-= 1;
        }
        return 1;
     }
    
    0 讨论(0)
  • 2021-01-14 17:07

    Subtract 3 until you either

    hit 0 - number was divisible by 3 (or)

    get a number less than 0 - number wasn't divisible

     if (number > 0)
     {
            while (number > 0)
            {
                number -= 3;
        }
    }
    else if( number < 0)
    {
        while number < 0:
            number += 3
    }
    return number == 0
    
    0 讨论(0)
提交回复
热议问题