Skip to content

Commit

Permalink
Fix ordering bug in U256 (FuelLabs#4527)
Browse files Browse the repository at this point in the history
## Description

The `Ord` implementation for `U256` is incorrect and would have some
values be both inferior and superior to each other at once which, among
other things, breaks division.

Fixes FuelLabs#4513

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
  • Loading branch information
IGI-111 authored May 3, 2023
1 parent ab679d9 commit cb7651f
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions sway-lib-std/src/u256.sw
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,34 @@ impl U256 {

impl core::ops::Ord for U256 {
fn gt(self, other: Self) -> bool {
self.a > other.a || (self.a == other.a && self.b > other.b || (self.b == other.b && self.c > other.c || (self.c == other.c && self.d > other.d)))
}
self.a > other.a ||
(self.a == other.a && (self.b > other.b ||
(self.b == other.b && (self.c > other.c ||
(self.c == other.c && self.d > other.d)))) )
}

fn lt(self, other: Self) -> bool {
self.a < other.a || (self.a == other.a && self.b < other.b || (self.b == other.b && self.c < other.c || (self.c == other.c && self.d < other.d)))
self.a < other.a ||
(self.a == other.a && (self.b < other.b ||
(self.b == other.b && (self.c < other.c ||
(self.c == other.c && self.d < other.d)))) )
}
}

#[test]
fn test_u256_ord() {
assert(U256::from((0, 0, 0, 1)) < U256::from((0, u64::max(), 0, 0)));
assert(!(U256::from((0, 0, 0, 1)) > U256::from((0, u64::max(), 0, 0))));

assert(U256::from((0, u64::max(), 0, 0)) > U256::from((0, 0, 0, 1)));
assert(!(U256::from((0, u64::max(), 0, 0)) < U256::from((0, 0, 0, 1))));

assert(U256::max() > U256::from((0, 0, u64::max(), u64::max())));
assert(!(U256::max() < U256::from((0, 0, u64::max(), u64::max()))));
assert(U256::from((0, 0, u64::max(), u64::max())) < U256::max());
assert(!(U256::from((0, 0, u64::max(), u64::max())) > U256::max()));
}

impl core::ops::BitwiseAnd for U256 {
fn binary_and(self, other: Self) -> Self {
let (value_word_1, value_word_2, value_word_3, value_word_4) = self.decompose();
Expand Down

0 comments on commit cb7651f

Please sign in to comment.