Low-Level C & Bit Tricksfoundational
How do you multiply without using multiply or divide instructions for a multiplier constant of 10, 31, 132?
0 upvotes
Practice with AISoon
Decompose each constant into sums/differences of power-of-two multiples, since multiplying by 2^k is a left shift (x << k). Choose the form with the fewest shift/add ops.
- × 10 =
8x + 2x=(x << 3) + (x << 1) - × 31 =
32x − x=(x << 5) − x(one shift and one subtract — cheaper than the additive form) - × 132 =
128x + 4x=(x << 7) + (x << 2)
c
#include <stdint.h>uint32_t mul10(uint32_t x) { return (x << 3) + (x << 1); }uint32_t mul31(uint32_t x) { return (x << 5) - x; }uint32_t mul132(uint32_t x) { return (x << 7) + (x << 2); }
Why this works: any constant has a binary expansion, so c * x = Σ (x << i) over the set bits i of c. Using subtraction lets you collapse runs of consecutive 1-bits (this is the idea behind canonical signed digit / Booth recoding): 31 = 0b11111, five set bits would be four adds, but 31 = 32 − 1 reduces it to one shift + one subtract.
Notes:
- Compilers already do this ("strength reduction") for constant multipliers, so you rarely write it by hand except on MCUs lacking a hardware multiplier or in hand-tuned DSP code.
- Watch for overflow: the intermediate
x << 7must fit in the chosen integer width; useuint32_t/uint64_tappropriately. - Division by a constant is also done without a divide instruction, but via a multiply-by-reciprocal-and-shift trick — not by shifts alone (only division by powers of two is a plain shift).
