Commit cd3a827
Merge #31
31: Add Average trait with integer average computation r=cuviper a=althonos
*This is actually a copy of #20, I had to reopen a PR to address the fixes as I deleted the repository in between*
Hi there !
This PR adds a new trait Average with two methods Average.average_ceil and Average.average_floor that uses bitwise operations to compute the average of two integers without overflowing. Reference is here, but this is probably known to people thanks to the Hacker's Delight.
Basically:
⌊(x+y)/2⌋ = (x&y) + ((x^y) >> 1)
⌈(x+y)/2⌉ = (x|y) - ((x^y) >> 1)
It comes with a blanket implementation for all Integer implementors that are closed under the -+|&^>> operators; in particular, this blanket implementation works for the BigInt and BigUint structs.
In terms of performance, this implementation is about 1.5 times faster than a naive implementation that checks for overflow, and as fast as an implementation that doesn't (i.e. (x+y)/2).
I'll add more tests for the std primitives, please do tell me if anything else needs to be changed.
Co-authored-by: Martin Larralde <martin.larralde@ens-paris-saclay.fr>
Co-authored-by: Josh Stone <cuviper@gmail.com>4 files changed
Lines changed: 596 additions & 0 deletions
0 commit comments