701

How would you divide a number by 3 without using *, /, +, -, %, operators?

The number may be signed or unsigned.

user16217248
  • 3,119
  • 19
  • 19
  • 37
Green goblin
  • 9,898
  • 13
  • 71
  • 100
  • 2
    This one's hard, since you can't use `+` or `-`. You could technically implement an adder using only logical operators... – Mysticial Jul 27 '12 at 19:39
  • 1
    Are you 100% positive that `+` was in the list of things you can't use? – Mooing Duck Jul 27 '12 at 19:44
  • is it the unary `+`, `-` allowed? – moooeeeep Jul 27 '12 at 19:49
  • 8
    The identified duplicate isn't a duplicate. Note that several answers here use neither bit shifting or addition since this question didn't restrict a solution to those operations. – Michael Burr Jul 28 '12 at 00:37
  • 4
    BTW: The other question was about **checking if** a number is divisible by 3. This question is about **dividing** by 3. – wildplasser Jul 30 '12 at 13:57
  • I'd be interested in seeing some set-based solutions to the problem (however inefficient they may be). A "simple" recursive CTE should be sufficient, I think. Was the question always tagged as `c` and `bitwise`? – Daniel B Jul 31 '12 at 14:03
  • 1
    For those interested, I posted [this](http://codegolf.stackexchange.com/q/6836/3862) on codegolf.stackexchange. – Gaffi Aug 02 '12 at 20:48
  • 3
    Perhaps the interviewer meant to ask "How do you divide by **2** without using blah blah blah". That would be a sane question that most developers should be able to answer. – Sam Elstob Aug 09 '12 at 12:09
  • 4
    x /= 3; does not use the / operator, /= is a different operator. – James Aug 21 '12 at 15:13
  • 28
    This question is offtopic to SO. It belongs to http://codegolf.stackexchange.com/ – Kromster Jun 03 '14 at 04:28
  • Use the `div_t` structure, and then get the `quot` and `rem` members – lost_in_the_source Dec 07 '14 at 17:00
  • 3
    I'm voting to close this question as off-topic because it is too broad and off-topic, belongs on codegolf.stackexchange.com. The quality of the present answers is depressing and this post has overall very little value. – Lundin Jan 23 '18 at 12:25
  • **Note**: Language specific challenge is highly discouraged on PPCG. PPCG is not a place to dump every off-topic but funny SO question. – user202729 Mar 16 '18 at 14:31
  • Similar answer are found in https://stackoverflow.com/questions/171301. – Friedrich -- Слава Україні Apr 13 '20 at 01:24

48 Answers48

554

This is a simple function which performs the desired operation. But it requires the + operator, so all you have left to do is to add the values with bit-operators:

// replaces the + operator
int add(int x, int y)
{
    while (x) {
        int t = (x & y) << 1;
        y ^= x;
        x = t;
    }
    return y;
}

int divideby3(int num)
{
    int sum = 0;
    while (num > 3) {
        sum = add(num >> 2, sum);
        num = add(num >> 2, num & 3);
    }
    if (num == 3)
        sum = add(sum, 1);
    return sum; 
}

As Jim commented this works, because:

  • n = 4 * a + b
  • n / 3 = a + (a + b) / 3
  • So sum += a, n = a + b, and iterate

  • When a == 0 (n < 4), sum += floor(n / 3); i.e. 1, if n == 3, else 0

qwertz
  • 14,614
  • 10
  • 34
  • 46
  • 96
    This is probably the answer Oracle is looking for. It shows you know how the +, -, * and / operators are actually implemented on the CPU: simple bitwise operations. – craig65535 Jul 27 '12 at 21:55
  • +1, although it needs some additional logic to handle negative numbers. – hatchet - done with SOverflow Jul 27 '12 at 23:59
  • 21
    This works because n = 4a + b, n/3 = a + (a+b)/3, so sum += a, n = a + b, and iterate. When a == 0 (n < 4), sum += floor(n/3); i.e., 1 if n == 3, else 0. – Jim Balter Jul 28 '12 at 05:36
  • 7
    Here's a trick i found which got me a similar solution. In decimal: `1 / 3 = 0.333333`, the repeating numbers make this easy to calculate using `a / 3 = a/10*3 + a/100*3 + a/1000*3 + (..)`. In binary it's almost the same: `1 / 3 = 0.0101010101 (base 2)`, which leads to `a / 3 = a/4 + a/16 + a/64 + (..)`. Dividing by 4 is where the bit shift comes from. The last check on num==3 is needed because we've only got integers to work with. – Yorick Sijsling Jul 30 '12 at 12:40
  • 4
    In base 4 it gets even better: `a / 3 = a * 0.111111 (base 4) = a * 4^-1 + a * 4^-2 + a * 4^-3 + (..) = a >> 2 + a >> 4 + a >> 6 + (..)`. The base 4 also explains why only 3 is rounded up at the end, while 1 and 2 can be rounded down. – Yorick Sijsling Jul 30 '12 at 13:04
  • 1
    I'm trying to understand the above solution. Can anyone help in understanding what does 'num & 3' represent? Thanks – while1 Jul 31 '12 at 13:59
  • 2
    @while1: it's bitwise AND operation. Also, a well-known fact is that for `n == 2^k` the following is true: `x % n == x & (n-1)`, so here `num & 3` is used to perform `num % 4` while `%` is not allowed. – aplavin Jul 31 '12 at 20:24
  • 1
    The actual ALU in a CPU would probably be based on combinational logic though, wouldn't it? – Peter Aug 02 '12 at 01:03
  • It seems tricky to make this work for signed int. Translating the negative number to 2s complement is straightforward enough, but then negating the answer after doing the division without using `-` seems hard without assuming how the platform represents negative numbers. – jxh Aug 22 '12 at 22:21
  • Is there a way to have this handle any divisor? – zero_cool Apr 22 '22 at 00:57
440

Idiotic conditions call for an idiotic solution:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE * fp=fopen("temp.dat","w+b");
    int number=12346;
    int divisor=3;
    char * buf = calloc(number,1);
    fwrite(buf,number,1,fp);
    rewind(fp);
    int result=fread(buf,divisor,number,fp);
    printf("%d / %d = %d", number, divisor, result);
    free(buf);
    fclose(fp);
    return 0;
}

If also the decimal part is needed, just declare result as double and add to it the result of fmod(number,divisor).

Explanation of how it works

  1. The fwrite writes number bytes (number being 123456 in the example above).
  2. rewind resets the file pointer to the front of the file.
  3. fread reads a maximum of number "records" that are divisor in length from the file, and returns the number of elements it read.

If you write 30 bytes then read back the file in units of 3, you get 10 "units". 30 / 3 = 10

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 1
    I like the fact that the `memset()` call has *two* (inconsequential) bugs. – Michael Burr Jul 27 '12 at 20:50
  • 2
    @Matteo: I dunno - I think it was already correct technically (a `memset()` that doesn't do anything to a buffer that doesn't need anything done to it is OK, right?) and it might help the interviewee find out something about the interviewer. – Michael Burr Jul 27 '12 at 20:59
  • 1
    Something else interesting: this solution doesn't work reliably on Windows (at least Win7 x64). However, I think that's a good thing because it made me to learn something new about Windows. It will return 0 for the `fread()` call because the `ReadFile()` Win32 API checks to see if the buffer you provided is large enough (at least by being 'valid memory' from the OS point of view) before it even tries to read data from the file. Since `ReadFile()` is asked to read 3 times more data than is allocated with `malloc()`, there's a good chance the memory won't be valid. – Michael Burr Jul 27 '12 at 21:23
  • By the way - the Windows 'problem' can be fixed by using `malloc(number << 2)` - as long as `number` is non-negative and small enough to avoid overflow, of course. – Michael Burr Jul 27 '12 at 21:28
  • @MichaelBurr: I don't know if the standard is fine with reading from uninitialized memory. Still, I could just replace `malloc`+`memset` with a plain `calloc`. As for the Windows behavior, I think it's allowed by the standard, so I should probably think about something even more idiotic. :) – Matteo Italia Jul 27 '12 at 21:32
  • @Matteo: the memory returned by `malloc()` is indeterminate rather than uninitialized. Since `fread()` and `fwrite()` access the buffer as `unsigned char`, the buffer access is fine (`unsigned char` access cannot have a trap representation). So not explicitly initializing the buffer is OK. The standard is pretty wide open as far as what's allowed to cause an I/O operation to fail, so I think the Windows behavior is fine. I look forward to any further 'enhanced' algorithm you might come up with. :) But maybe enough brain power/amusement has been expended on this already? – Michael Burr Jul 27 '12 at 21:49
  • @MichaelBurr: I'm confident that what you said on the uninitialized memory is correct, but I just wanted to stay on the safe side. :) I was thinking about an algorithm using some pointer arithmetic, but it turned out it gave erratic results for numbers not exact multiples of three. – Matteo Italia Jul 27 '12 at 22:35
  • I do love the ingenuity, but [fread](http://opensource.apple.com/source/Libc/Libc-167/stdio.subproj/fread.c) uses + and -. The question was to not **use** + and -, instead of not **typing** them in into your source code. – earlNameless Jul 28 '12 at 19:27
  • 13
    @earlNameless: you don't know what they use inside, they are in the black box of "implementation defined". Nothing stops them to just use bitwise operators; anyway, they are outside the domain of my code, so that's not my problem. :) – Matteo Italia Jul 29 '12 at 01:02
  • 8
    @IvoFlipse from I can clean, you get a big *something* and shove it into something three times too small, and then see how much fitted in. That about is a third. – AncientSwordRage Jul 29 '12 at 15:00
  • 5
    @IvoFlipse: The [function signatures](http://linux.die.net/man/3/fwrite) of fread and fwrite are critical to understanding how this solution works. Essentially, fread and fwrite take both an argument for the number of elements to write, and an argument for the length of each element (in bytes). Because of this, you can use clever trickery to essentially use the division operation that must exist within the library code. – crazy2be Jul 29 '12 at 17:33
  • 29
    asked the best C programmer (and most socially awkward) at our company to explain the code. after he did, i said it was pretty ingenious. He said 'this dreck is not a solution' and asked me to leave his desk –  Jul 30 '12 at 12:45
  • @MatteoItalia, if true, then using [BigInteger](http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigInteger.html) is much easier than this hackery. – earlNameless Jul 30 '12 at 19:44
  • 3
    @earlNameless: since when `BigInteger` was a part of the C standard library? And anyhow it wouldn't be as fun. :) – Matteo Italia Jul 30 '12 at 22:12
  • 6
    @cvursache I think the point is that the question is so brain dead, that a brain dead answer is allowed. The "best C programmer" at your company" could just as easily have said "that dreck is not a (proper) question". – JeremyP Jul 31 '12 at 10:18
  • 19
    @JeremyP: exactly. My point is that if in real life I was given a compiler without support for arithmetic *the only sensible thing would be to ask for a better compiler*, because working in those conditions doesn't make any sense. If the interviewer wanted to check my knowledge of how to implement division with bitwise operations he could just be straightforward and ask it as a theoretical question; these kind of "trick exercises" just scream for answers like this. – Matteo Italia Jul 31 '12 at 11:22
  • @user234461: internally it may use whatever it likes, it's not my problem. *My* code doesn't use any arithmetic operator. – Matteo Italia Aug 20 '18 at 19:24
  • @MatteoItalia I don't mean the implementation. I mean the line that calls *fread*. – user234461 Aug 21 '18 at 10:19
  • @user234461: the only `+` in my code is in `fopen`, but it's not an operator; still, it can be removed by doing two separate `fopen` calls. – Matteo Italia Aug 21 '18 at 10:37
  • @MatteoItalia What makes you think it's not an operator? Semantically, adding a `+` to `"r"` or `"w"` changes the set of permitted IO operations from *{read}* or *{write}* to *{read, write}*. If `"r"` and "`w`" are defined as sets of semantic meanings both belonging to the set of all possible sets of semantics of `fopen`, then by definition, `+` is an operator because it maps elements of the set to other elements of the set. – user234461 Aug 22 '18 at 10:27
  • @user234461 it all depends from whether the supercatsol preripens or what; if it's an endomorphism between two disjoint categories it may be understood as a vice-major in the C standard, but otherwise you should see that it teases, and pre-ripens also, like car-horning or Antans. – Matteo Italia Aug 24 '18 at 07:40
  • 1
    @MatteoItalia I liked your answer already, but here's another thumbs up for "supercatsol preripens". :-) – Steve Summit Jul 13 '22 at 19:08
310
log(pow(exp(number),0.33333333333333333333)) /* :-) */
Alan Curry
  • 14,255
  • 3
  • 32
  • 33
  • 2
    This might actually work if rounded properly and if the number isn't too large. – Mysticial Jul 27 '12 at 19:57
  • 254
    Improved version: log(pow(exp(number),sin(atan2(1,sqrt(8))))) – Alan Curry Jul 28 '12 at 00:14
  • @bitmask, math functions are usually implemented directly in asm. – SingerOfTheFall Aug 10 '12 at 09:40
  • 8
    i just typed it in my js console, it doesn't work with a number higher than 709 (may be its just my system) `Math.log(Math.pow(Math.exp(709),0.33333333333333333333))` and `Math.log(Math.pow(Math.exp(709),Math.sin(Math.atan2(1,Math.sqrt(8)))))` – Shaheer Aug 30 '12 at 13:12
209
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{

    int num = 1234567;
    int den = 3;
    div_t r = div(num,den); // div() is a standard C function.
    printf("%d\n", r.quot);

    return 0;
}
nos
  • 223,662
  • 58
  • 417
  • 506
113

You can use (platform dependent) inline assembly, e.g., for x86: (also works for negative numbers)

#include <stdio.h>

int main() {
  int dividend = -42, divisor = 5, quotient, remainder;

  __asm__ ( "cdq; idivl %%ebx;"
          : "=a" (quotient), "=d" (remainder)
          : "a"  (dividend), "b"  (divisor)
          : );

  printf("%i / %i = %i, remainder: %i\n", dividend, divisor, quotient, remainder);
  return 0;
}
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • This fails on the assumption that the answer has to be written in C. – JeremyP Jul 31 '12 at 10:20
  • 2
    @JeremyP doesn't your comment fail on the assumption that the answer can't be written in C? The question is tagged "C" after all. – Seth Carnegie Aug 01 '12 at 18:33
  • 1
    @SethCarnegie The answer is not written in C is my point. x86 assembler is not part of the standard. – JeremyP Aug 02 '12 at 13:29
  • 1
    @JeremyP that is true, but the `asm` directive is. And I would add that C compilers are not the only ones that have inline assemblers, Delphi has that as well. – Seth Carnegie Aug 02 '12 at 18:01
  • 7
    @SethCarnegie The `asm` directive is only mentioned in the C99 standard under Appendix J - common extensions. – JeremyP Aug 03 '12 at 09:49
  • @SethCarnegie not just Delphi, most Pascal/Object Pascal dialects do, via the asm/end construct (nicer integration imo, but going OT here). – Thomas Aug 07 '12 at 07:27
  • 2
    Fails in arm-eabi-gcc. – Damian Yerrick Jul 26 '15 at 17:34
  • @tepples For an x68 incompatible architecture you have to use other instructions, of course. – moooeeeep Jul 28 '15 at 18:59
  • @moooeeeep: I must have missed at least one processor architecture, then: neither the Motorola MC6800 & descendants nor those of the 68000 ("68k") have gone by `x68`. – greybeard Jul 30 '15 at 05:51
  • @DamianYerrick Well duh, it's x86 asm, not ARM / MIPS. – cat Sep 20 '16 at 22:43
  • @cat You appear to have missed my point. If the instructor states that the required language is "C", it implies to me that "The architecture on which your program will be built and tested is unspecified." – Damian Yerrick Sep 21 '16 at 16:37
107

Use itoa to convert to a base 3 string. Drop the last trit and convert back to base 10.

// Note: itoa is non-standard but actual implementations
// don't seem to handle negative when base != 10.
int div3(int i) {
    char str[42];
    sprintf(str, "%d", INT_MIN); // Put minus sign at str[0]
    if (i>0)                     // Remove sign if positive
        str[0] = ' ';
    itoa(abs(i), &str[1], 3);    // Put ternary absolute value starting at str[1]
    str[strlen(&str[1])] = '\0'; // Drop last digit
    return strtol(str, NULL, 3); // Read back result
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bo Lu
  • 641
  • 1
  • 4
  • 7
57

(note: see Edit 2 below for a better version!)

This is not as tricky as it sounds, because you said "without using the [..] + [..] operators". See below, if you want to forbid using the + character all together.

unsigned div_by(unsigned const x, unsigned const by) {
  unsigned floor = 0;
  for (unsigned cmp = 0, r = 0; cmp <= x;) {
    for (unsigned i = 0; i < by; i++)
      cmp++; // that's not the + operator!
    floor = r;
    r++; // neither is this.
  }
  return floor;
}

then just say div_by(100,3) to divide 100 by 3.


Edit: You can go on and replace the ++ operator as well:

unsigned inc(unsigned x) {
  for (unsigned mask = 1; mask; mask <<= 1) {
    if (mask & x)
      x &= ~mask;
    else
      return x & mask;
  }
  return 0; // overflow (note that both x and mask are 0 here)
}

Edit 2: Slightly faster version without using any operator that contains the +,-,*,/,% characters.

unsigned add(char const zero[], unsigned const x, unsigned const y) {
  // this exploits that &foo[bar] == foo+bar if foo is of type char*
  return (int)(uintptr_t)(&((&zero[x])[y]));
}

unsigned div_by(unsigned const x, unsigned const by) {
  unsigned floor = 0;
  for (unsigned cmp = 0, r = 0; cmp <= x;) {
    cmp = add(0,cmp,by);
    floor = r;
    r = add(0,r,1);
  }
  return floor;
}

We use the first argument of the add function because we cannot denote the type of pointers without using the * character, except in function parameter lists, where the syntax type[] is identical to type* const.

FWIW, you can easily implement a multiplication function using a similar trick to use the 0x55555556 trick proposed by AndreyT:

int mul(int const x, int const y) {
  return sizeof(struct {
    char const ignore[y];
  }[x]);
}
Community
  • 1
  • 1
bitmask
  • 32,434
  • 14
  • 99
  • 159
43

It is easily possible on the Setun computer.

To divide an integer by 3, shift right by 1 place.

I'm not sure whether it's strictly possible to implement a conforming C compiler on such a platform though. We might have to stretch the rules a bit, like interpreting "at least 8 bits" as "capable of holding at least integers from -128 to +127".

Mechanical snail
  • 29,755
  • 14
  • 88
  • 113
  • 8
    The problem is that you don't have a "shift right by 1 place" operator in C. The `>>` operator is the "division by 2^n" operator, i.e. it is specified in terms of arithmetic, not machine representation. – R.. GitHub STOP HELPING ICE Aug 22 '12 at 06:44
  • The Setun computer is not binary in any sense of the word, so the instruction set must be definitely different. However, I am not at all familiar with the operation of that computer, so I cannot confirm if the response is really correct - but at least it makes sense - and is highly original. +1 – virolino Feb 07 '19 at 06:57
34

Here's my solution:

public static int div_by_3(long a) {
    a <<= 30;
    for(int i = 2; i <= 32 ; i <<= 1) {
        a = add(a, a >> i);
    }
    return (int) (a >> 32);
}

public static long add(long a, long b) {
    long carry = (a & b) << 1;
    long sum = (a ^ b);
    return carry == 0 ? sum : add(carry, sum);
}

First, note that

1/3 = 1/4 + 1/16 + 1/64 + ...

Now, the rest is simple!

a/3 = a * 1/3  
a/3 = a * (1/4 + 1/16 + 1/64 + ...)
a/3 = a/4 + a/16 + 1/64 + ...
a/3 = a >> 2 + a >> 4 + a >> 6 + ...

Now all we have to do is add together these bit shifted values of a! Oops! We can't add though, so instead, we'll have to write an add function using bit-wise operators! If you're familiar with bit-wise operators, my solution should look fairly simple... but just in-case you aren't, I'll walk through an example at the end.

Another thing to note is that first I shift left by 30! This is to make sure that the fractions don't get rounded off.

11 + 6

1011 + 0110  
sum = 1011 ^ 0110 = 1101  
carry = (1011 & 0110) << 1 = 0010 << 1 = 0100  
Now you recurse!

1101 + 0100  
sum = 1101 ^ 0100 = 1001  
carry = (1101 & 0100) << 1 = 0100 << 1 = 1000  
Again!

1001 + 1000  
sum = 1001 ^ 1000 = 0001  
carry = (1001 & 1000) << 1 = 1000 << 1 = 10000  
One last time!

0001 + 10000
sum = 0001 ^ 10000 = 10001 = 17  
carry = (0001 & 10000) << 1 = 0

Done!

It's simply carry addition that you learned as a child!

111
 1011
+0110
-----
10001

This implementation failed because we can not add all terms of the equation:

a / 3 = a/4 + a/4^2 + a/4^3 + ... + a/4^i + ... = f(a, i) + a * 1/3 * 1/4^i
f(a, i) = a/4 + a/4^2 + ... + a/4^i

Suppose the reslut of div_by_3(a) = x, then x <= floor(f(a, i)) < a / 3. When a = 3k, we get wrong answer.

Ray
  • 1,647
  • 13
  • 16
tschultz
  • 128
  • 1
  • 6
  • 2
    does it work for input of 3? 1/4, 1/16, ... all return 0 for 3, so would sum to 0, but 3/3 = 1. – hatchet - done with SOverflow Jul 27 '12 at 21:55
  • 1
    The logic is good but the implementation is problematic. The series approximation of `n/3` is always less than `n/3` which means that for any `n=3k` the result would be `k-1` instead of `k`. – Xyand Jul 28 '12 at 00:40
  • @Albert, This was the first approach I tried, with a couple variations, but they all failed on either certain numbers evenly divisible by 3 or evenly divisible by 2 (depending on the variation). So I tried something more straightforward. I would like to see an implementation of this approach that works, to see where I was screwing up. – hatchet - done with SOverflow Jul 28 '12 at 00:53
  • @hatchet, The question is closed so I can't post a new answer but the idea is to implement binary div. I should be easy to look it up. – Xyand Jul 28 '12 at 17:06
  • [Hacker's delight has some rounding method to get the correct result](http://www.hackersdelight.org/divcMore.pdf) – phuclv Jul 27 '18 at 16:57
25

To divide a 32-bit number by 3 one can multiply it by 0x55555556 and then take the upper 32 bits of the 64 bit result.

Now all that's left to do is to implement multiplication using bit operations and shifts...

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
18

Yet another solution. This should handle all ints (including negative ints) except the min value of an int, which would need to be handled as a hard coded exception. This basically does division by subtraction but only using bit operators (shifts, xor, & and complement). For faster speed, it subtracts 3 * (decreasing powers of 2). In c#, it executes around 444 of these DivideBy3 calls per millisecond (2.2 seconds for 1,000,000 divides), so not horrendously slow, but no where near as fast as a simple x/3. By comparison, Coodey's nice solution is about 5 times faster than this one.

public static int DivideBy3(int a) {
    bool negative = a < 0;
    if (negative) a = Negate(a);
    int result;
    int sub = 3 << 29;
    int threes = 1 << 29;
    result = 0;
    while (threes > 0) {
        if (a >= sub) {
            a = Add(a, Negate(sub));
            result = Add(result, threes);
        }
        sub >>= 1;
        threes >>= 1;
    }
    if (negative) result = Negate(result);
    return result;
}
public static int Negate(int a) {
    return Add(~a, 1);
}
public static int Add(int a, int b) {
    int x = 0;
    x = a ^ b;
    while ((a & b) != 0) {
        b = (a & b) << 1;
        a = x;
        x = a ^ b;
    }
    return x;
}

This is c# because that's what I had handy, but differences from c should be minor.

mmdemirbas
  • 9,060
  • 5
  • 45
  • 53
  • You only need to try to subtract sub once, because if you could have subtracted it twice then you could have subtracted it the previous iteration when it was twice as big as it is now. – Neil Jul 28 '12 at 00:25
  • Does `(a >= sub)` count as a subtraction? – Neil Jul 28 '12 at 00:26
  • @Neil, I think you may be right. The inner while could be replaced with a simple if, saving an unneeded comparison from the second iteration of the loop. Regarding >= being subtraction...I hope not, because that would make doing this quite difficult! I see your point, but I think I would lean on the side that says >= does not count as subtraction. – hatchet - done with SOverflow Jul 28 '12 at 00:34
  • @Neil, I made that change, which cut the time in half (also saved unneeded Negates). – hatchet - done with SOverflow Jul 28 '12 at 00:45
16

It's really quite easy.

if (number == 0) return 0;
if (number == 1) return 0;
if (number == 2) return 0;
if (number == 3) return 1;
if (number == 4) return 1;
if (number == 5) return 1;
if (number == 6) return 2;

(I have of course omitted some of the program for the sake of brevity.) If the programmer gets tired of typing this all out, I'm sure that he or she could write a separate program to generate it for him. I happen to be aware of a certain operator, /, that would simplify his job immensely.

thedayturns
  • 9,723
  • 5
  • 33
  • 41
14

Using counters is a basic solution:

int DivBy3(int num) {
    int result = 0;
    int counter = 0;
    while (1) {
        if (num == counter)       //Modulus 0
            return result;
        counter = abs(~counter);  //++counter

        if (num == counter)       //Modulus 1
            return result;
        counter = abs(~counter);  //++counter

        if (num == counter)       //Modulus 2
            return result;
        counter = abs(~counter);  //++counter

        result = abs(~result);    //++result
    }
}

It is also easy to perform a modulus function, check the comments.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
GJ.
  • 10,810
  • 2
  • 45
  • 62
11

This one is the classical division algorithm in base 2:

#include <stdio.h>
#include <stdint.h>

int main()
{
  uint32_t mod3[6] = { 0,1,2,0,1,2 };
  uint32_t x = 1234567; // number to divide, and remainder at the end
  uint32_t y = 0; // result
  int bit = 31; // current bit
  printf("X=%u   X/3=%u\n",x,x/3); // the '/3' is for testing

  while (bit>0)
  {
    printf("BIT=%d  X=%u  Y=%u\n",bit,x,y);
    // decrement bit
    int h = 1; while (1) { bit ^= h; if ( bit&h ) h <<= 1; else break; }
    uint32_t r = x>>bit;  // current remainder in 0..5
    x ^= r<<bit;          // remove R bits from X
    if (r >= 3) y |= 1<<bit; // new output bit
    x |= mod3[r]<<bit;    // new remainder inserted in X
  }
  printf("Y=%u\n",y);
}
Eric Bainville
  • 9,738
  • 1
  • 25
  • 27
10

Write the program in Pascal and use the DIV operator.

Since the question is tagged , you can probably write a function in Pascal and call it from your C program; the method for doing so is system-specific.

But here's an example that works on my Ubuntu system with the Free Pascal fp-compiler package installed. (I'm doing this out of sheer misplaced stubbornness; I make no claim that this is useful.)

divide_by_3.pas :

unit Divide_By_3;
interface
    function div_by_3(n: integer): integer; cdecl; export;
implementation
    function div_by_3(n: integer): integer; cdecl;
    begin
        div_by_3 := n div 3;
    end;
end.

main.c :

#include <stdio.h>
#include <stdlib.h>

extern int div_by_3(int n);

int main(void) {
    int n;
    fputs("Enter a number: ", stdout);
    fflush(stdout);
    scanf("%d", &n);
    printf("%d / 3 = %d\n", n, div_by_3(n));
    return 0;
}

To build:

fpc divide_by_3.pas && gcc divide_by_3.o main.c -o main

Sample execution:

$ ./main
Enter a number: 100
100 / 3 = 33
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
8
int div3(int x)
{
  int reminder = abs(x);
  int result = 0;
  while(reminder >= 3)
  {
     result++;

     reminder--;
     reminder--;
     reminder--;
  }
  return result;
}
Amir Saniyan
  • 13,014
  • 20
  • 92
  • 137
  • 3
    ++ and -- operaors are diferent from + and - operaors! In assembly language there are two instructions `ADD` and `INC` that they have not same opcodes. – Amir Saniyan Aug 05 '12 at 13:50
7

Didn't cross-check if this answer is already published. If the program need to be extended to floating numbers, the numbers can be multiplied by 10*number of precision needed and then the following code can be again applied.

#include <stdio.h>

int main()
{
    int aNumber = 500;
    int gResult = 0;

    int aLoop = 0;

    int i = 0;
    for(i = 0; i < aNumber; i++)
    {
        if(aLoop == 3)
        {
           gResult++;
           aLoop = 0;
        }  
        aLoop++;
    }

    printf("Reulst of %d / 3 = %d", aNumber, gResult);

    return 0;
}
PermanentGuest
  • 5,213
  • 2
  • 27
  • 36
7

This should work for any divisor, not only three. Currently only for unsigned, but extending it to signed should not be that difficult.

#include <stdio.h>

unsigned sub(unsigned two, unsigned one);
unsigned bitdiv(unsigned top, unsigned bot);
unsigned sub(unsigned two, unsigned one)
{
unsigned bor;
bor = one;
do      {
        one = ~two & bor;
        two ^= bor;
        bor = one<<1;
        } while (one);
return two;
}

unsigned bitdiv(unsigned top, unsigned bot)
{
unsigned result, shift;

if (!bot || top < bot) return 0;

for(shift=1;top >= (bot<<=1); shift++) {;}
bot >>= 1;

for (result=0; shift--; bot >>= 1 ) {
        result <<=1;
        if (top >= bot) {
                top = sub(top,bot);
                result |= 1;
                }
        }
return result;
}

int main(void)
{
unsigned arg,val;

for (arg=2; arg < 40; arg++) {
        val = bitdiv(arg,3);
        printf("Arg=%u Val=%u\n", arg, val);
        }
return 0;
}
wildplasser
  • 43,142
  • 8
  • 66
  • 109
7

Would it be cheating to use the / operator "behind the scenes" by using eval and string concatenation?

For example, in Javacript, you can do

function div3 (n) {
    var div = String.fromCharCode(47);
    return eval([n, div, 3].join(""));
}
Peter Olson
  • 139,199
  • 49
  • 202
  • 242
6

First that I've come up with.

irb(main):101:0> div3 = -> n { s = '%0' + n.to_s + 's'; (s % '').gsub('   ', ' ').size }
=> #<Proc:0x0000000205ae90@(irb):101 (lambda)>
irb(main):102:0> div3[12]
=> 4
irb(main):103:0> div3[666]
=> 222

EDIT: Sorry, I didn't notice the tag C. But you can use the idea about string formatting, I guess...

defhlt
  • 1,775
  • 2
  • 17
  • 24
6

Using BC Math in PHP:

<?php
    $a = 12345;
    $b = bcdiv($a, 3);   
?>

MySQL (it's an interview from Oracle)

> SELECT 12345 DIV 3;

Pascal:

a:= 12345;
b:= a div 3;

x86-64 assembly language:

mov  r8, 3
xor  rdx, rdx   
mov  rax, 12345
idiv r8
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pedro L.
  • 7,376
  • 3
  • 25
  • 27
  • 2
    Cool story, this is tagged C and has been so since day one. In addition, you completely fail to grasp the point of the question. – Lundin Jan 23 '18 at 12:16
5

Using Hacker's Delight Magic number calculator

int divideByThree(int num)
{
  return (fma(num, 1431655766, 0) >> 32);
}

Where fma is a standard library function defined in math.h header.

Jainendra
  • 24,713
  • 30
  • 122
  • 169
5

The following script generates a C program that solves the problem without using the operators * / + - %:

#!/usr/bin/env python3

print('''#include <stdint.h>
#include <stdio.h>
const int32_t div_by_3(const int32_t input)
{
''')

for i in range(-2**31, 2**31):
    print('    if(input == %d) return %d;' % (i, i / 3))


print(r'''
    return 42; // impossible
}
int main()
{
    const int32_t number = 8;
    printf("%d / 3 = %d\n", number, div_by_3(number));
}
''')
Mechanical snail
  • 29,755
  • 14
  • 88
  • 113
4

Solution using fma() library function, works for any positive number:

#include <stdio.h>
#include <math.h>

int main()
{
    int number = 8;//Any +ve no.
    int temp = 3, result = 0;
    while(temp <= number){
        temp = fma(temp, 1, 3); //fma(a, b, c) is a library function and returns (a*b) + c.
        result = fma(result, 1, 1);
    } 
    printf("\n\n%d divided by 3 = %d\n", number, result);
}

See my another answer.

Community
  • 1
  • 1
Eight
  • 4,194
  • 5
  • 30
  • 51
4

How about this approach (c#)?

private int dividedBy3(int n) {
        List<Object> a = new Object[n].ToList();
        List<Object> b = new List<object>();
        while (a.Count > 2) {
            a.RemoveRange(0, 3);
            b.Add(new Object());
        }
        return b.Count;
    }
mclafee
  • 1,406
  • 3
  • 18
  • 25
4

I think the right answer is:

Why would I not use a basic operator to do a basic operation?

Gregoire
  • 3,735
  • 3
  • 25
  • 37
  • Because what they want to know is if you know how the processor works internally... using a math operator will in the end perform an operation very similar to the above answer. – RaptorX Nov 05 '12 at 18:57
  • Or they wan to know if you can recognize an useless problem. – Gregoire Nov 20 '12 at 11:14
  • 1
    @Gregoire I agree, There is aboloultley no need to do such an implementation, Bit in comercial life (Orcale) it is neccessary to avoid fulfilling useless requirments: The correct answer is: "This does not make any sense at all, why loose money for that?") – AlexWien Dec 14 '12 at 13:56
4

First:

x/3 = (x/4) / (1-1/4)

Then figure out how to solve x/(1 - y):

x/(1-1/y)
  = x * (1+y) / (1-y^2)
  = x * (1+y) * (1+y^2) / (1-y^4)
  = ...
  = x * (1+y) * (1+y^2) * (1+y^4) * ... * (1+y^(2^i)) / (1-y^(2^(i+i))
  = x * (1+y) * (1+y^2) * (1+y^4) * ... * (1+y^(2^i))

with y = 1/4:

int div3(int x) {
    x <<= 6;    // need more precise
    x += x>>2;  // x = x * (1+(1/2)^2)
    x += x>>4;  // x = x * (1+(1/2)^4)
    x += x>>8;  // x = x * (1+(1/2)^8)
    x += x>>16; // x = x * (1+(1/2)^16)
    return (x+1)>>8; // as (1-(1/2)^32) very near 1,
                     // we plus 1 instead of div (1-(1/2)^32)
}

Although it uses +, but somebody already implements add by bitwise op.

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
Zang MingJie
  • 5,164
  • 1
  • 14
  • 27
3

Use cblas, included as part of OS X's Accelerate framework.

[02:31:59] [william@relativity ~]$ cat div3.c
#import <stdio.h>
#import <Accelerate/Accelerate.h>

int main() {
    float multiplicand = 123456.0;
    float multiplier = 0.333333;
    printf("%f * %f == ", multiplicand, multiplier);
    cblas_sscal(1, multiplier, &multiplicand, 1);
    printf("%f\n", multiplicand);
}

[02:32:07] [william@relativity ~]$ clang div3.c -framework Accelerate -o div3 && ./div3
123456.000000 * 0.333333 == 41151.957031
wjl
  • 7,143
  • 1
  • 30
  • 49
  • Well, that was just an implementation detail so I could type it as 3.0 / 1.0 instead of 0.333333, but I should play by the rules. Fixed! – wjl Jul 30 '12 at 15:48
  • I originally had it as 3.0 / 1.0, which did in my test. By using a higher precision number, they should get a reasonably accurate result. https://gist.github.com/3401496 – wjl Aug 20 '12 at 06:00
3

Generally, a solution to this would be:

log(pow(exp(numerator),pow(denominator,-1)))

nKn
  • 13,691
  • 9
  • 45
  • 62
2

Okay I think we all agree that this isn't a real world problem. So just for fun, here's how to do it with Ada and multithreading:

with Ada.Text_IO;

procedure Divide_By_3 is

   protected type Divisor_Type is
      entry Poke;
      entry Finish;
   private
      entry Release;
      entry Stop_Emptying;
      Emptying : Boolean := False;
   end Divisor_Type;

   protected type Collector_Type is
      entry Poke;
      entry Finish;
   private
      Emptying : Boolean := False;
   end Collector_Type;

   task type Input is
   end Input;
   task type Output is
   end Output;

   protected body Divisor_Type is
      entry Poke when not Emptying and Stop_Emptying'Count = 0 is
      begin
         requeue Release;
      end Poke;
      entry Release when Release'Count >= 3 or Emptying is
         New_Output : access Output;
      begin
         if not Emptying then
            New_Output := new Output;
            Emptying := True;
            requeue Stop_Emptying;
         end if;
      end Release;
      entry Stop_Emptying when Release'Count = 0 is
      begin
         Emptying := False;
      end Stop_Emptying;
      entry Finish when Poke'Count = 0 and Release'Count < 3 is
      begin
         Emptying := True;
         requeue Stop_Emptying;
      end Finish;
   end Divisor_Type;

   protected body Collector_Type is
      entry Poke when Emptying is
      begin
         null;
      end Poke;
      entry Finish when True is
      begin
         Ada.Text_IO.Put_Line (Poke'Count'Img);
         Emptying := True;
      end Finish;
   end Collector_Type;

   Collector : Collector_Type;
   Divisor : Divisor_Type;

   task body Input is
   begin
      Divisor.Poke;
   end Input;

   task body Output is
   begin
      Collector.Poke;
   end Output;

   Cur_Input : access Input;

   -- Input value:
   Number : Integer := 18;
begin
   for I in 1 .. Number loop
      Cur_Input := new Input;
   end loop;
   Divisor.Finish;
   Collector.Finish;
end Divide_By_3;
flyx
  • 35,506
  • 7
  • 89
  • 126
  • This is tagged C and has been so since day one. Your answer is off-topic. – Lundin Jan 23 '18 at 12:21
  • Digging up old, closed questions and writing this kind of comment on the answers is as well. It is a waste of time for both of us since you have to write the comment and I see the notification, click on it and need to grasp the context. Neither will it educate me (I cannot even remember writing this) nor will it improve the answer (you are not really thinking I will translate that to C, are you). What are you trying to achieve? – flyx Jan 23 '18 at 13:39
  • The problem is that the question _isn't_ closed and has therefore spawned and keeps spawning a flood of off-topic, low quality crap answers. I'm trying to improve the quality of the site by going through the answers, flagging non-answers and down voting off-topic ones. This is btw all community wiki so no rep is affected. – Lundin Jan 23 '18 at 13:42
  • Okay, I stand corrected. Wouldn't it be easier to close the question to stop new answers? – flyx Jan 23 '18 at 14:00
  • You have my sword. – flyx Jan 23 '18 at 14:13
2

Quite amused none answered with a generic division:

/* For the given integer find the position of MSB */
int find_msb_loc(unsigned int n)
{
    if (n == 0)
        return 0;

    int loc = sizeof(n)  * 8 - 1;
    while (!(n & (1 << loc)))
        loc--;
    return loc;
}


/* Assume both a and b to be positive, return a/b */
int divide_bitwise(const unsigned int a, const unsigned int b)
{
    int int_size = sizeof(unsigned int) * 8;
    int b_msb_loc = find_msb_loc(b);

    int d = 0; // dividend
    int r = 0; // reminder
    int t_a = a;
    int t_a_msb_loc = find_msb_loc(t_a);
    int t_b = b << (t_a_msb_loc - b_msb_loc);

    int i;
    for(i = t_a_msb_loc; i >= b_msb_loc; i--)  {
        if (t_a > t_b) {
            d = (d << 1) | 0x1;
            t_a -= t_b; // Not a bitwise operatiion
            t_b = t_b >> 1;
         }
        else if (t_a == t_b) {
            d = (d << 1) | 0x1;
            t_a = 0;
        }
        else { // t_a < t_b
            d = d << 1;
            t_b = t_b >> 1;
        }
    }

    r = t_a;
    printf("==> %d %d\n", d, r);
    return d;
}

The bitwise addition has already been given in one of the answers so skipping it.

Xolve
  • 22,298
  • 21
  • 77
  • 125
2

All answers are probably not that what the interviewer liked to hear:

My answer:

"I would never do that, who will me pay for such silly things. Nobody will have an advantage on that, its not faster, its only silly. Prozessor designers have to know that, but this must then work for all numbers, not only for division by 3"

AlexWien
  • 28,470
  • 6
  • 53
  • 83
  • What makes you say the interviewer don't want to hear this? Any candidate giving such an answer on one of my interviews just increased their chance of getting the job. One sane person in a flood of... – Lundin Jan 23 '18 at 12:21
1
#include <stdio.h>

typedef struct { char a,b,c; } Triple;

unsigned long div3(Triple *v, char *r) {
  if ((long)v <= 2)  
    return (unsigned long)r;
  return div3(&v[-1], &r[1]);
}

int main() {
  unsigned long v = 21; 
  int r = div3((Triple*)v, 0); 
  printf("%ld / 3 = %d\n", v, r); 
  return 0;
}
perreal
  • 94,503
  • 21
  • 155
  • 181
1

Why don't we just apply the definition studied at College? The result maybe inefficient but clear, as the multiplication is just a recursive subtraction and subtraction is an addition, then the addition can be performed by a recursive xor/and logic port combination.

#include <stdio.h>

int add(int a, int b){
   int rc;
   int carry;
   rc = a ^ b; 
   carry = (a & b) << 1;
   if (rc & carry) 
      return add(rc, carry);
   else
      return rc ^ carry; 
}

int sub(int a, int b){
   return add(a, add(~b, 1)); 
}

int div( int D, int Q )
{
/* lets do only positive and then
 * add the sign at the end
 * inversion needs to be performed only for +Q/-D or -Q/+D
 */
   int result=0;
   int sign=0;
   if( D < 0 ) {
      D=sub(0,D);
      if( Q<0 )
         Q=sub(0,Q);
      else
         sign=1;
   } else {
      if( Q<0 ) {
         Q=sub(0,Q);
         sign=1;
      } 
   }
   while(D>=Q) {
      D = sub( D, Q );
      result++;
   }
/*
* Apply sign
*/
   if( sign )
      result = sub(0,result);
   return result;
}

int main( int argc, char ** argv ) 
{
    printf( "2 plus 3=%d\n", add(2,3) );
    printf( "22 div 3=%d\n", div(22,3) );
    printf( "-22 div 3=%d\n", div(-22,3) );
    printf( "-22 div -3=%d\n", div(-22,-3) );
    printf( "22 div 03=%d\n", div(22,-3) );
    return 0;
}

As someone says... first make this work. Note that algorithm should work for negative Q...

Jekyll
  • 1,434
  • 11
  • 13
1

If you remind yourself standard school method of division and do it in binary, you will discover that in case of 3 you only divide and subtract a limited set of values (from 0 to 5 in this case). These can be treated with a switch statement to get rid of arithmetic operators.

static unsigned lamediv3(unsigned n)
{
  unsigned result = 0, remainder = 0, mask = 0x80000000;

  // Go through all bits of n from MSB to LSB.
  for (int i = 0; i < 32; i++, mask >>= 1)
  {
    result <<= 1;
    // Shift in the next bit of n into remainder.
    remainder = remainder << 1 | !!(n & mask);

    // Divide remainder by 3, update result and remainer.
    // If remainder is less than 3, it remains intact.
    switch (remainder)
    {
    case 3:
      result |= 1;
      remainder = 0;
      break;

    case 4:
      result |= 1;
      remainder = 1;
      break;

    case 5:
      result |= 1;
      remainder = 2;
      break;
    }
  }

  return result;
}

#include <cstdio>

int main()
{
  // Verify for all possible values of a 32-bit unsigned integer.
  unsigned i = 0;

  do
  {
    unsigned d = lamediv3(i);

    if (i / 3 != d)
    {
      printf("failed for %u: %u != %u\n", i, d, i / 3);
      return 1;
    }
  }
  while (++i != 0);
}
kyku
  • 5,892
  • 4
  • 43
  • 51
0
#!/bin/ruby

def div_by_3(i)
  i.div 3        # always return int http://www.ruby-doc.org/core-1.9.3/Numeric.html#method-i-div
end
A B
  • 2,013
  • 2
  • 21
  • 22
0

if we consider __div__ is not orthographically /

def divBy3(n):
    return n.__div__(3)

print divBy3(9), 'or', 9//3
0

3 in base 2 is 11.

So just do long division (like in middle school) in base 2 by 11. It is even easier in base 2 than base 10.

For each bit position starting with most significant:

Decide if prefix is less than 11.

If it is output 0.

If it is not output 1, and then substitute prefix bits for appropriate change. There are only three cases:

 11xxx ->    xxx    (ie 3 - 3 = 0)
100xxx ->   1xxx    (ie 4 - 3 = 1)
101xxx ->  10xxx    (ie 5 - 3 = 2)

All other prefixes are unreachable.

Repeat until lowest bit position and you're done.

Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319
0

It seems no one mentioned the division criterion for 3 represented in binary - sum of even digits should equal the sum of odd digits (similar to criterion of 11 in decimal). There are solutions using this trick under Check if a number is divisible by 3.

I suppose that this is the possible duplicate that Michael Burr's edit mentioned.

Community
  • 1
  • 1
yoniLavi
  • 2,624
  • 1
  • 24
  • 30
0

Where InputValue is the number to divide by 3

SELECT AVG(NUM) 
  FROM (SELECT InputValue NUM from sys.dual
         UNION ALL SELECT 0 from sys.dual
         UNION ALL SELECT 0 from sys.dual) divby3
Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
Craig
  • 1
  • 1
0

I would use this code to divide all positive, non float numbers. Basically you want to align the divisor bits to the left to match the dividend bits. For each segment of the dividend (size of divisor) you want to check to make sure if the the segment of dividend is greater than the divisor then you want to Shift Left and then OR in the first registrar. This concept was originally created in 2004 (standford I believe), Here is a C version which uses that concept. Note: (I modified it a bit)

int divide(int a, int b)
{
    int c = 0, r = 32, i = 32, p = a + 1;
    unsigned long int d = 0x80000000;

    while ((b & d) == 0)
    {
        d >>= 1;
        r--;
    }

    while (p > a)
    {
        c <<= 1;
        p = (b >> i--) & ((1 << r) - 1);
        if (p >= a)
            c |= 1;
    }
    return c; //p is remainder (for modulus)
}

Example Usage:

int n = divide( 3, 6); //outputs 2
MysteryDev
  • 610
  • 2
  • 12
  • 31
0

To divide a number by 3, without using multiplication, division, remainder, subtraction or addition operations, in Assembly programming language, the only instructions available are LEA (address effective load), SHL (move left) and SHR (move to right ).

With this solution I have not used operations associated with the operators + - * /%

I assumed to have the output number in fixed point format (16 bit of integer part and 16 bit of decimal part) and the input number is of type short int; however I have approximated the number of outputs because that I can only trust the integer part and therefore I return a value of type short int.

65536/6 is the fixed point value equivalent to 1/3 floating point and is equal to 21845.

21845 = 16384 + 4096 + 1024 + 256 + 64 + 16 + 4 + 1.

So, to do the multiplication by 1/3 (21845), I use the instructions LEA and SHL.

short int DivideBy3( short int num )
//In : eax= 16 Bit short int input number (N)
//Out: eax= N/3 (32 Bit fixed point output number
//          (Bit31-Bit16: integer part, Bit15-Bit0: digits after comma)
{
   __asm
   {
      movsx eax, num          // Get first argument

      // 65536 / 3 = 21845 = 16384 + 4096 + 1024 + 256 + 64 + 16 + 4 + 1

      lea edx,[4*eax+eax]     // EDX= EAX * 5
      shl eax,4
      lea edx,[eax+edx]       // EDX= EDX + EAX * 16
      shl eax,2
      lea edx,[eax+edx]       // EDX= EDX + EAX * 64
      shl eax,2
      lea edx,[eax+edx]       // EDX= EDX + EAX * 256
      shl eax,2
      lea edx,[eax+edx]       // EDX= EDX + EAX * 1024
      shl eax,2
      lea edx,[eax+edx]       // EDX= EDX + EAX * 4096
      shl eax,2
      lea edx,[eax+edx+08000h] // EDX= EDX + EAX * 16384

      shr edx,010h
      movsx eax,dx

   }
   // Return with result in EAX
}

It also works with negative numbers; the result has a minimum approximation with positive numbers (-1 on the last digit after the comma).

If you intend not to use the operators + - * /% to perform division by 3, but you can use the operations associated with them, I propose a second solution.

int DivideBy3Bis( short int num )
//In : eax= 16 Bit short int input number (N)
//Out: eax= N/3 (32 Bit fixed point output number
//          (Bit31-Bit16: integer part, Bit15-Bit0: digits after comma)
{
   __asm
   {
      movsx   eax, num        // Get first argument

      mov     edx,21845
      imul    edx
   }
   // Return with result in EAX
}
Paolo Fassin
  • 361
  • 2
  • 11
-1

Here it is in Python with, basically, string comparisons and a state machine.

def divide_by_3(input):
  to_do = {}
  enque_index = 0
  zero_to_9 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
  leave_over = 0
  for left_over in (0, 1, 2):
    for digit in zero_to_9:
      # left_over, digit => enque, leave_over
      to_do[(left_over, digit)] = (zero_to_9[enque_index], leave_over)
      if leave_over == 0:
        leave_over = 1
      elif leave_over == 1:
        leave_over = 2
      elif leave_over == 2 and enque_index != 9:
        leave_over = 0
        enque_index = (1, 2, 3, 4, 5, 6, 7, 8, 9)[enque_index]
  answer_q = []
  left_over = 0
  digits = list(str(input))
  if digits[0] == "-":
    answer_q.append("-")
  digits = digits[1:]
  for digit in digits:
    enque, left_over = to_do[(left_over, int(digit))]
    if enque or len(answer_q):
      answer_q.append(enque)
  answer = 0
  if len(answer_q):
    answer = int("".join([str(a) for a in answer_q]))
  return answer
Dave Aaron Smith
  • 4,517
  • 32
  • 37
-1

Well you could think of using a graph/tree like structure to solve the problem. Basically generate as many vertices as the number that is to be divided by 3. Then keep pairing each un-paired vertex with two other vertices.

Rough pseudocode:

function divide(int num)
    while(num!=0)
        Add a new vertice to vertiexList.
        num--
    quotient = 0
    for each in vertexList(lets call this vertex A)
        if vertexList not empty
            Add an edge between A and another vertex(say B)
        else
            your Remainder is 1 and Quotient is quotient
        if vertexList not empty
            Add an edge between A and another vertex(say C)
        else
            your remainder is 2 and Quotient is quotient
        quotient++
        remove A, B, C from vertexList
    Remainder is 0 and Quotient is quotient

This can obviously be optimized and the complexity depends on how big you number is, but it shoud work providing you can do ++ and --. It's as good as counting only cooler.

sleeping.ninja
  • 607
  • 1
  • 10
  • 21
-1

This will work:

smegma$ curl http://www.wolframalpha.com/input/?i=14+divided+by+3 2>/dev/null | gawk 'match($0, /link to /input/\?i=([0-9.+-]+)/, ary) { print substr( $0, ary[1, "start"], ary[1, "length"] )}' 4.6666666666666666666666666666666666666666666666666666

Just substitute '14' and '3' with your numbers.

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
CPRitter
  • 151
  • 3
-2

Using a Linux shell script:

#include <stdio.h>
int main()
{
    int number = 30;
    char command[25];
    snprintf(command, 25, "echo $((%d %c 3)) ", number, 47);
    system( command );
    return 0;
}

See my another answer.

Community
  • 1
  • 1
Eight
  • 4,194
  • 5
  • 30
  • 51
-2

Good 'ol bc:

$ num=1337; printf "scale=5;${num}\x2F3;\n" | bc
445.66666
Lee Netherton
  • 21,347
  • 12
  • 68
  • 102
-2

Here's a method my Grandfather taught me when I was a child. It requires + and / operators but it makes calculations easy.

Add the individual digits together and then see if its a multiple of 3.

But this method works for numbers above 12.

Example: 36,

3+6=9 which is a multiple of 3.

42,

4+2=6 which is a multiple of 3.

Adnan Zahid
  • 573
  • 1
  • 10
  • 38
  • 2
    How do you determine what the digits are without dividing by 10? How do you add them without using `+`? – Keith Thompson Mar 24 '15 at 18:51
  • 2
    Besides, this determines if a number is a multiple of 3, it doesn't tell you want number it's a multiple of. In you're example, you don't get 12 or 14. – Teepeemm Sep 27 '16 at 00:33