integer division with controlled rounding in Math.h
Summary:
C++'s integer division performs truncation, but it is fairly
common that people actually want to round up. There are actually
four rounding modes that make some sense: toward negative infinity
(floor), toward positive infinity (ceil), toward zero (truncation),
and away from zero (?). It is pretty common that code that wants ceil
actually writes (a + b - 1) / b, which doesn't work at all for negative
values (and has a potential overflow issue). This diff adds 4 templated
functions for performing integer division: divFloor, divCeil, divTrunc,
and divRoundAway. They are not subject to unnecessary internal underflow
or overflow, and they work correctly across their entire input domain.
I did a bit of benchmarking across x86_64, arm64, and 32-bit ARM.
Only 32-bit ARM was different. That's not surprising since it doesn't
have an integer division instruction, and the function that implements
integer division doesn't produce the remainder for free. On 32-bit ARM
a branchful version that doesn't need the modulus is used.
Reviewed By: yfeldblum
Differential Revision:
D3806743
fbshipit-source-id:
c14c56717e96f135321920e64acbfe9dcb1fe039