views:

2303

answers:

8
int x = n / 3;  // <-- make this faster

// for instance

int a = n * 3; // <-- normal integer multiplication

int b = (n << 1) + n; // <-- potentially faster multiplication
+2  A: 

I don't know if it's faster but if you want to use a bitwise operator to perform binary division you can use the shift and subtract method described at this page:

  • Set quotient to 0
  • Align leftmost digits in dividend and divisor
  • Repeat:
    • If that portion of the dividend above the divisor is greater than or equal to the divisor:
      • Then subtract divisor from that portion of the dividend and
      • Concatentate 1 to the right hand end of the quotient
      • Else concatentate 0 to the right hand end of the quotient
    • Shift the divisor one place right
  • Until dividend is less than the divisor:
  • quotient is correct, dividend is remainder
  • STOP
Mark Cidade
I suspect that this is not faster. It is more or less a algorithm for doing binary division.
Greg Dean
I finally found it! Years and years ago I came across a 6502 assembly routine for division and somehow lost it over time. 6502 has no mul/div opcodes, so this is the only way. Now I know! Thanks.
spoulson
A: 

There's no way to do this that I can tell.

However if you wanted to divide by a power of 2 (and didn't care about the remainder) you could do

int x = n >> 2; // divide by 4
Dre
+2  A: 

If you really want to see this article on integer division, but it only has academic merit ... it would be an interesting application that actually needed to perform that benefited from that kind of trick.

Rob Walker
looking for something a little more practical, thanks though
Greg Dean
+29  A: 

This is the fastest as the compiler will optimize it if it can depending on the output processor.

int a;
int b;

a = some value;
b = a / 3;
KPexEA
This is unfortunately what I thought as well.
Greg Dean
On second thought I think what you are tying to say is that the following. If "some value" is known ahead of time the compiler will optimize the evaluation of some value/3. However I am interested in the case where some value is determined at runtime
Greg Dean
turns out regardless of some value being known the compiler will optimize it to something similar to n * 0x55555556 >> 32thanks
Greg Dean
The most straightforward way is usually the best, isn't it?
mxg
Wow, biggest bullshit I ever read. Sorry to say so, I don't want to be rude, but every compiler I know turns the code above into a div CPU instruction (when available) and this is anything but fast. It is one of the slowest CPU instructions that exist!
Mecki
@Mecki - Apparently the only shit here is your compiler. Everyone else seems to have one that uses something like i * 0x55555556 >> 32
Greg Dean
+8  A: 

See How To Divide By 3 for an extended discussion of more efficiently dividing by 3, focused on doing FPGA arithmetic operations.

Also relevant:

Jay
pretty cool stuff however, I should have specified that I am confined to something x86-ish
Greg Dean
+46  A: 

The guy who said "leave it to the compiler" was right, but I don't have the "reputation" to mod him up or comment. I asked gcc to compile int test(int a) { return a / 3; } for an ix86 and then disassembled the output. Just for academic interest, what it's doing is roughly multiplying by 0x55555556 and then taking the top 32 bits of the 64 bit result of that. You can demonstrate this to yourself with eg:

$ ruby -e 'puts(60000 * 0x55555556 >> 32)'
20000
$ ruby -e 'puts(72 * 0x55555556 >> 32)'
24
$ 

The wikipedia page on Montgomery division is hard to read but fortunately the compiler guys have done it so you don't have to.

voted up to help you get the "reputation" you desire
nickf
A: 

Depending on your platform and depending on your C compiler, a native solution like just using

y = x / 3

Can be fast or it can be awfully slow (even if division is done entirely in hardware, if it is done using a DIV instruction, this instruction is about 3 to 4 times slower than a multiplication on modern CPUs). Very good C compilers with optimization flags turned on may optimize this operation, but if you want to be sure, you are better off optimizing it yourself.

For optimization it is important to have integer numbers of a known size. In C int has no known size (it can vary by platform and compiler!), so you are better using C99 fixed-size integers. The code below assumes that you want to divide an unsigned 32-bit integer by three and that you C compiler knows about 64 bit integer numbers (NOTE: Even on a 32 bit CPU architecture most C compilers can handle 64 bit integers just fine):

static inline uint32_t divby3 (
    uint32_t divideMe
) {
    return (uint32_t)((0xAAAAAAABULL * divideMe) >> 33);
}

As crazy as this might sound, but the method above indeed does divide by 3. All it needs for doing so is a single 64 bit multiplication and a shift (like I said, multiplications might be 3 to 4 times faster than divisions on your CPU). In a 64 bit application this code will be a lot faster than in a 32 bit application (in a 32 bit application multiplying two 64 bit numbers take 3 multiplications and 3 additions on 32 bit values) - however, it might be still faster than a division on a 32 bit machine.

On the other hand, if your compiler is a very good one and knows the trick how to optimize integer division by a constant (latest GCC does, I just checked), it will generate the code above anyway (GCC will create exactly this code for "/3" if you enable at least optimization level 1). For other compilers... you cannot rely or expect that it will use tricks like that, even though this method is very well documented and mentioned everywhere on the Internet.

Problem is that it only works for constant numbers, not for variable ones. You always need to know the magic number (here 0xAAAAAAAB) and the correct operations after the multiplication (shifts and/or additions in most cases) and both is different depending on the number you want to divide by and both take too much CPU time to calculate them on the fly (that would be slower than hardware division). However, it's easy for a compiler to calculate these during compile time (where one second more or less compile time plays hardly a role).

Mecki
I wish I could tell the compiler NOT to do that sort of thing sometimes. This makes for faster code, but also bigger code.
Matthias Wandel
A: 

What if you really don't want to multiply or divide? Here is is an approximation I just invented. It works because (x/3) = (x/4) + (x/12). But since (x/12) = (x/4) / 3 we just have to repeat the process until its good enough.

#include <stdio.h>

void main()
{
    int n = 1000;
    int a,b;
    a = n >> 2;
    b = (a >> 2);
    a += b;
    b = (b >> 2);
    a += b;
    b = (b >> 2);
    a += b;
    b = (b >> 2);
    a += b;
    printf("a=%d\n", a);
}

The result is 330. It could be made more accurate using b = ((b+2)>>2); to account for rounding.

If you are allowed to multiply, just pick a suitable approximation for (1/3), with a power-of-2 divisor. For example, n * (1/3) ~= n * 43 / 128 = (n * 43) >> 7.

This technique is most useful in Indiana.

Steve Hanov