integer division with controlled rounding in Math.h
authorNathan Bronson <ngbronson@fb.com>
Wed, 7 Sep 2016 22:50:38 +0000 (15:50 -0700)
committerFacebook Github Bot 4 <facebook-github-bot-4-bot@fb.com>
Wed, 7 Sep 2016 22:53:43 +0000 (15:53 -0700)
commit1d9d5cbe1dde81dd5fae5aada11a7091dbe4aa6b
tree24f0ca188fea448aaf1f79850b5b5de2d34b1922
parentf6b5f78bd533b91f51c3afc6d310698a42edb65d
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
folly/Makefile.am
folly/Math.h [new file with mode: 0644]
folly/test/Makefile.am
folly/test/MathBenchmark.cpp [new file with mode: 0644]
folly/test/MathTest.cpp [new file with mode: 0644]