Skip to content

Commit

Permalink
Merge branch 'master' into bitzoic-signed-int-subtraction
Browse files Browse the repository at this point in the history
  • Loading branch information
bitzoic authored Jul 25, 2024
2 parents 24d0c53 + 624b664 commit 6147358
Show file tree
Hide file tree
Showing 55 changed files with 676 additions and 500 deletions.
20 changes: 18 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,25 @@ Description of the upcoming release here.

- [#258](https://github.com/FuelLabs/sway-libs/pull/258) Fixes incorrect instructions on how to run tests in README and docs hub.
- [#262](https://github.com/FuelLabs/sway-libs/pull/262) Fixes incorrect ordering comparison for IFP64, IFP128 and IFP256.
- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Fixes `I256`'s returned bits.
- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Fixes `I128` and `I256`'s zero or "indent" value.
- [#268](https://github.com/FuelLabs/sway-libs/pull/268) Fixes subtraction involving negative numbers for `I8`, `I16`, `I32`, `I64`, `I128`, and `I256`.


#### Breaking

- Some breaking change here 1
- Some breaking change here 2
- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Removes the `TwosComplement` trait in favor of `WrappingNeg`.

The following demonstrates the breaking change. While this example code uses the `I8` type, the same logic may be applied to the `I16`, `I32`, `I64`, `I128`, and `I256` types.

Before:
```sway
let my_i8 = i8::zero();
let twos_complement = my_i8.twos_complement();
```

After:
```sway
let my_i8 = i8::zero();
let wrapping_neg = my_i8.wrapping_neg();
```
12 changes: 8 additions & 4 deletions libs/src/signed_integers/common.sw
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
library;

/// Trait for the Two's Complement of a value.
pub trait TwosComplement {
/// Returns the two's complement of a value.
/// Wrapping (modular) negation. Computes -self, wrapping around at the boundary of the type.
pub trait WrappingNeg {
/// Negates a signed number.
///
/// # Additional Information
///
/// * The only case where such wrapping can occur is when one negates self::min(). In such a case, this function returns self::min() itself.
///
/// # Returns
///
/// * [Self] - The value as two's complement.
fn twos_complement(self) -> Self;
fn wrapping_neg(self) -> Self;
}
36 changes: 14 additions & 22 deletions libs/src/signed_integers/i128.sw
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
library;

use std::u128::U128;
use ::signed_integers::common::TwosComplement;
use ::signed_integers::common::WrappingNeg;
use ::signed_integers::errors::Error;

/// The 128-bit signed integer type.
Expand Down Expand Up @@ -31,11 +31,11 @@ impl I128 {
///
/// fn foo() {
/// let zero = I128::indent();
/// assert(zero == U128::from((1, 0)));
/// assert(zero == (U128::max() / (U128::from(0, 2)) - U128::from(0,1));
/// }
/// ```
pub fn indent() -> U128 {
U128::from((1, 0))
U128::from((9223372036854775808, 0))
}
}

Expand Down Expand Up @@ -189,7 +189,7 @@ impl I128 {
///
/// # Additional Information
///
/// The zero value of I128 is U128::from((1, 0)).
/// The zero value of I128 is U128::from((9223372036854775808, 0)).
///
/// # Returns
///
Expand Down Expand Up @@ -269,7 +269,7 @@ impl I128 {
///
/// fn foo() {
/// let i128 = I128::zero();
/// assert(i128.underlying() == U128::from((1, 0)));
/// assert(i128.underlying() == U128::from((9223372036854775808, 0)));
/// }
/// ```
pub fn underlying(self) -> U128 {
Expand Down Expand Up @@ -342,10 +342,8 @@ impl core::ops::Multiply for I128 {
/// Multiply a I128 with a I128. Panics of overflow.
fn multiply(self, other: Self) -> Self {
let mut res = Self::new();
if (self.underlying > Self::indent()
|| self.underlying == Self::indent())
&& (other.underlying > Self::indent()
|| other.underlying == Self::indent())
if self.underlying >= Self::indent()
&& other.underlying >= Self::indent()
{
res = Self::from_uint(
(self.underlying - Self::indent()) * (other.underlying - Self::indent()) + Self::indent(),
Expand All @@ -356,16 +354,14 @@ impl core::ops::Multiply for I128 {
res = Self::from_uint(
(Self::indent() - self.underlying) * (Self::indent() - other.underlying) + Self::indent(),
);
} else if (self.underlying > Self::indent()
|| self.underlying == Self::indent())
} else if self.underlying >= Self::indent()
&& other.underlying < Self::indent()
{
res = Self::from_uint(
Self::indent() - (self.underlying - Self::indent()) * (Self::indent() - other.underlying),
);
} else if self.underlying < Self::indent()
&& (other.underlying > Self::indent()
|| other.underlying == Self::indent())
&& other.underlying >= Self::indent()
{
res = Self::from_uint(
Self::indent() - (other.underlying - Self::indent()) * (Self::indent() - self.underlying),
Expand Down Expand Up @@ -400,15 +396,11 @@ impl core::ops::Subtract for I128 {
}
}

impl TwosComplement for I128 {
fn twos_complement(self) -> Self {
if self.underlying == Self::indent()
|| self.underlying > Self::indent()
{
return self;
impl WrappingNeg for I128 {
fn wrapping_neg(self) -> Self {
if self == self::min() {
return self::min()
}
let u_one = U128::from((0, 1));
let res = I128::from_uint(!self.underlying + u_one);
res
self * Self::neg_from(U128::from((0, 1)))
}
}
13 changes: 6 additions & 7 deletions libs/src/signed_integers/i16.sw
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
library;

use ::signed_integers::errors::Error;
use ::signed_integers::common::TwosComplement;
use ::signed_integers::common::WrappingNeg;

/// The 16-bit signed integer type.
///
Expand Down Expand Up @@ -383,12 +383,11 @@ impl core::ops::Subtract for I16 {
}
}

impl TwosComplement for I16 {
fn twos_complement(self) -> Self {
if self.underlying >= Self::indent() {
return self;
impl WrappingNeg for I16 {
fn wrapping_neg(self) -> Self {
if self == self::min() {
return self::min()
}
let res = Self::from_uint(!self.underlying + 1u16);
res
self * Self::neg_from(1u16)
}
}
Loading

0 comments on commit 6147358

Please sign in to comment.