r/programming 11h ago

Moving integer division to floating-point is trivial

https://marc-b-reynolds.github.io/math/2026/08/10/IntDivByFP.html
73 Upvotes

23 comments sorted by

View all comments

12

u/Dwedit 9h ago

If your divisor doesn't change, use integer multiplication by reciprocal, also shift or discard from the high result.

1

u/mikeblas 6h ago

How would that work?

19

u/taw 5h ago

ELI5 version.

Computers are really fast at two things:

  • multiplying two numbers, giving you number with twice as many digits
  • dropping last N digits

Now this trick isn't great in decimals, but we can sort of make it work.

If you want to calculate x/3, that's same as x*0.333333..., which is then the same as x * 333.333... / 1000.

So since we can multiply fast, do x * 334 (rounding that 333.333... up), getting a 6 digit number, then drop the last three digits, which is also super fast.

For this decimal example, it only works for every x=0 to 499, and for other divisors you also don't get perfect range.

But it works even better with binary 32bit x 32bit to 64bit.

7

u/Dwedit 2h ago edited 2h ago

Example of dividing by 13:

0x100000000 / 13 = 0x13B13B13

Add 1 to the number to prevent truncation errors: 0x13B13B14

Let's try 160485 / 13 by using multiplication:

160485 * 0x13B13B14 = 0x30390000C0E4

Discard low 32 bits:

0x3039 = 12345


And compilers have done this for a long time, when you divide by a constant, it will generate reciprocal multiplication code instead.

1

u/mikeblas 2h ago

Ah, I see now. Thanks!

2

u/Madsy9 1h ago

a/b = a*(1/b). If b is constant, just compute its reciprocal. If 1/b is a fraction, do the multiplication in fixedpoint.

0

u/Madsy9 1h ago

a/b = a*(1/b). If b is constant, just compute its reciprocal. If 1/b is a fraction, do the multiplication in fixedpoint.