diff --git a/corelib/src/integer.cairo b/corelib/src/integer.cairo index aa96297595a..ffa1f11308f 100644 --- a/corelib/src/integer.cairo +++ b/corelib/src/integer.cairo @@ -2454,6 +2454,31 @@ impl I128Neg of Neg { } } +impl I128Mul of Mul { + 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 = (lhs_u127 * rhs_u127).try_into().expect('i128_mul Overflow'); + if res_neg { + -res + } else { + res + } + } +} +impl I128MulEq of MulEq { + #[inline(always)] + fn mul_eq(ref self: i128, other: i128) { + self = Mul::mul(self, other); + } +} + extern fn i128_diff(lhs: i128, rhs: i128) -> Result implicits(RangeCheck) nopanic; impl I128PartialOrd of PartialOrd { #[inline(always)] diff --git a/corelib/src/test/integer_test.cairo b/corelib/src/test/integer_test.cairo index d4ecb4938e3..08597f5c507 100644 --- a/corelib/src/test/integer_test.cairo +++ b/corelib/src/test/integer_test.cairo @@ -1698,6 +1698,14 @@ 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(@(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_lt(1_i128, 4_i128, '1 < 4'); assert_le(1_i128, 4_i128, '1 <= 4'); assert(!(4_i128 < 4_i128), '!(4 < 4)'); @@ -1744,3 +1752,21 @@ fn test_i128_add_overflow_1() { fn test_i128_add_overflow_2() { 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; +}