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 <[email protected]>
Co-authored-by: Josh Stone <[email protected]>4 files changed
+596
-0
lines changed
0 commit comments