Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added implementation for i128 mul. #3625

Merged
merged 1 commit into from
Sep 18, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Added implementation for i128 mul.
commit-id:e5ea59f5
orizi committed Sep 18, 2023
commit 1581e78feb5ff935fa7b47111c665e7d5b16faed
26 changes: 26 additions & 0 deletions corelib/src/integer.cairo
Original file line number Diff line number Diff line change
@@ -2359,6 +2359,32 @@ impl I128Neg of Neg<i128> {
}
}

impl I128Mul of Mul<i128> {
fn mul(lhs: i128, rhs: i128) -> i128 {
let (lhs_u127, lhs_neg) = match i128_diff(lhs, 0) {
Result::Ok(v) => (v, false),
Result::Err(v) => (~v + 1, true),
};
let (rhs_u127, res_neg) = match i128_diff(rhs, 0) {
Result::Ok(v) => (v, lhs_neg),
Result::Err(v) => (~v + 1, !lhs_neg),
};
let res_as_u128 = lhs_u127 * rhs_u127;
let res_as_felt252: felt252 = if res_neg {
-res_as_u128.into()
} else {
res_as_u128.into()
};
res_as_felt252.try_into().expect('i128_mul Overflow')
}
}
impl I128MulEq of MulEq<i128> {
#[inline(always)]
fn mul_eq(ref self: i128, other: i128) {
self = Mul::mul(self, other);
}
}

/// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**128 + lhs - rhs)`.
extern fn i128_diff(lhs: i128, rhs: i128) -> Result<u128, u128> implicits(RangeCheck) nopanic;
impl I128PartialOrd of PartialOrd<i128> {
32 changes: 32 additions & 0 deletions corelib/src/test/integer_test.cairo
Original file line number Diff line number Diff line change
@@ -1563,6 +1563,20 @@ fn test_i128_operators() {
assert_eq(@(-3_i128 + -6_i128), @-9_i128, '-3 + -6 == -9');
assert_eq(@(-3_i128 - -1_i128), @-2_i128, '-3 - -1 == -2');
assert_eq(@(-231_i128 - -131_i128), @-100_i128, '-231--131=-100');
assert_eq(@(1_i128 * 3_i128), @3_i128, '1 * 3 == 3');
assert_eq(@(7_i128 * 0_i128), @0_i128, '7 * 0 == 0');
assert_eq(@(2_i128 * 4_i128), @8_i128, '2 * 4 == 8');
assert_eq(@(-1_i128 * 3_i128), @-3_i128, '-1 * 3 == -3');
assert_eq(@(-2_i128 * 4_i128), @-8_i128, '-2 * 4 == -8');
assert_eq(@(1_i128 * -3_i128), @-3_i128, '1 * -3 == -3');
assert_eq(@(2_i128 * -4_i128), @-8_i128, '2 * -4 == -8');
assert_eq(@(-1_i128 * -3_i128), @3_i128, '-1 * -3 == 3');
assert_eq(@(-2_i128 * -4_i128), @8_i128, '-2 * -4 == 8');
assert_eq(
@(0x800000000000000_i128 * -0x100000000000000000_i128),
@-0x80000000000000000000000000000000_i128,
'failed MIN_I128 as mul result'
);
assert_lt(1_i128, 4_i128, '1 < 4');
assert_le(1_i128, 4_i128, '1 <= 4');
assert(!(4_i128 < 4_i128), '!(4 < 4)');
@@ -1622,6 +1636,24 @@ fn test_i128_add_underflow() {
-0x64000000000000000000000000000000_i128 + -0x1e000000000000000000000000000000_i128;
}

#[test]
#[should_panic]
fn test_i128_mul_overflow_1() {
0x10000000000000000000000000000000_i128 * 0x10000000000000000000000000000000_i128;
}

#[test]
#[should_panic]
fn test_i128_mul_overflow_2() {
0x11000000000000000000000000000000_i128 * 0x10000000000000000000000000000000_i128;
}

#[test]
#[should_panic]
fn test_i128_mul_overflow_3() {
2_i128 * 0x40000000000000000000000000000000_i128;
}

#[test]
fn test_signed_int_diff() {
assert_eq(@integer::i8_diff(3, 3).unwrap(), @0, 'i8: 3 - 3 == 0');