tags:

views:

393

answers:

4

Hi All

In my program I am using a lot of integer division by 10^x and integer mod function of power 10.

ex:

unsigned __int64 a = 12345;
a = a / 100;
....

or

unsigned __int64 a = 12345;
a = a % 1000;
....

If i am going to use bite shift >> , then i will get mode of 2^x, which is not what i want.

Is there any way, I can speed up my program in integer division and mod functions ?? Thank you

A: 

Not unless you're architecture supports Binary Coded Decimal, and even then only with lots of assembly messiness.

Autopulated
+3  A: 

From http://www.hackersdelight.org/divcMore.pdf

unsigned divu10(unsigned n) {
unsigned q, r;
q = (n >> 1) + (n >> 2);
q = q + (q >> 4);
q = q + (q >> 8);
q = q + (q >> 16);
q = q >> 3;
r = n - q*10;
return q + ((r + 6) >> 4);

}
stacker
+1 for actual answer (-dozen to everyone who uses it). Perhaps, the function should be declared as `inline`.
Li0liQ
To the people upvoting this, has anyone performance profiled it to make sure that it is actually faster? I cannot see anywhere that the article claims that the code is faster.
Mark Byers
Seven shifts, one multiplication, seven add/sub, and looks like 3 registers, sounds like a close call for speed. Probably depends on architecture and the context in which it's used.
Autopulated
Can't most CPUs do a div in a single clock (possibly pipelined) ? I would downvote this answer and encourage the OP to just use /.
keraba
As far as I know, integer division is typically *not* pipelined, and takes upwards of 15 cycles. That's just from memory though, don't quote me on it. But integer division is fairly slow. However, I'm not saying that this answer's algorithm is faster. It'll use more registers, that's for sure. And take up a lot more icache space.
jalf
If this was faster, the compiler was likely to implement the division with this method.
Mehrdad Afshari
It's an alternative whether or not it is faster depends on the processor used, think about embedded systems with weak processors instead of latest Intel or AMD processors
stacker
stacker: I would say it might work for systems with "weak compilers". To be fair, embedded systems usually have not so great compilers.
Mehrdad Afshari
@keraba: Downvote the anwer? You *downwote* answers in such cases? The answer is not incorrect, given the right situation. It might not deserve an upvote, but it certaily doesn't deserve a downvote.
AndreyT
@AndreyT: It might not be technically incorrect, but it's certainly incomplete.
Jason
+8  A: 

Short Answer: NO

Long Answer: NO.

Explanation:
The compiler is already optimizing statements like this for you.
If there is a technique for implementing this quicker than an integer division then the compiler already knows about it and will apply it (assuming you turn on optimizations).

If you provide the appropriate architecture flags as well then the compiler may even know about specific fast architecture specific assembles that will provide a nice trick for doing the operation otherwise it will apply the best trick for the generic architecture it was compiled for.

In short the compiler will beat the human 99.9999999% of the time in any optimization trick (try it remember to add the optimization flag and architecture flags). So the best you can normally do is equal the compiler.

If by some miracle you discover a method that has not already been found by the Assembly boffins that work closely with the backend compiler team. Then please let them know and the next version of the popular compilers will be updated with the 'unknown (google)' division by 10 optimization trick.

Martin York
I love this answer. Just the right combination of snarkiness and correctness.
Jason
A: 

If the divisor is an explicit compile-time constant (i.e. if your x in 10^x is a compile-time constant), there's absolutely no point in using anything else than the language-provided / and % operators. If there a meaningful way to speed them up for explicit powers of 10, any self-respecting compler will know how to do that and will do that for you.

The only situiation when you might think about a "custom" implementation (aside from a dumb compiler) is the situation when x is a run-time value. In that case you'd need some kind of decimal-shift and decimal-and analogy. On a binary machine, a speedup is probably possible, but I doubt that you'll be able to achieve anything practically meaningful. (If the numbers were stored in binary-decimal format, then it would be easy, but in "normal" cases - no.)

AndreyT