uint: Fix overflowing_neg by implementing two's complement #611
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The operation
overflowing_neg
on the primitive integer types in theRust standard library computes the negation of the integer value using
two's complement, i.e., it returns
!self + 1
.The current implementation of the uint library implemented
overflowing_neg
using!self
for non-zero values which is bit-wisenegation (NOT). This lead to behavior where 0 - 1 != -1 for
U256 with the
overflowing_neg
andoverflow_sub
operations.This patch adapts the
uint_overflowing_binop
macro to implement thetwo's complement correctly: Starting from the least significant word
we apply
u64::overflowing_neg
until we have seen the first one-bit inthe original integer, i.e., until
overflowing_neg
reports an overflow.Then we use bit-wise NOT for the remaining words
(cf. https://en.wikipedia.org/wiki/Two%27s_complement#Working_from_LSB_towards_MSB).