Sitelet https://github.com/starkware-libs/cairo/commit/862e8bd4d7f57bd41f20bb483f065a1f220b611f
Skip to content

Commit 862e8bd

Browse files
committed
bugfix(corelib): Made the panic message more exact for i128_mul.
Additionally improved performance of the implementation.
1 parent 0a554e2 commit 862e8bd

2 files changed

Lines changed: 32 additions & 9 deletions

File tree

‎corelib/src/integer.cairo‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,13 +2360,25 @@ impl I128Mul of Mul<i128> {
23602360
Ok(lt0) => (upcast(bounded_int::NegateHelper::negate(lt0)), !lhs_neg),
23612361
Err(ge0) => (upcast(ge0), lhs_neg),
23622362
};
2363-
let res_as_u128 = lhs_u127 * rhs_u127;
2364-
let res_as_felt252: felt252 = if res_neg {
2365-
-res_as_u128.into()
2363+
let (res_high, res_as_u128) = u128_wide_mul(lhs_u127, rhs_u127);
2364+
if res_high != 0 {
2365+
crate::panic_with_felt252('i128_mul Overflow');
2366+
}
2367+
if res_neg {
2368+
match downcast::<
2369+
_, bounded_int::BoundedInt<0, 0x80000000000000000000000000000000>,
2370+
>(res_as_u128) {
2371+
Some(magnitude) => upcast(bounded_int::NegateHelper::negate(magnitude)),
2372+
None => crate::panic_with_felt252('i128_mul Overflow'),
2373+
}
23662374
} else {
2367-
res_as_u128.into()
2368-
};
2369-
res_as_felt252.try_into().expect('i128_mul Overflow')
2375+
match downcast::<
2376+
_, bounded_int::BoundedInt<0, 0x7fffffffffffffffffffffffffffffff>,
2377+
>(res_as_u128) {
2378+
Some(magnitude) => upcast(magnitude),
2379+
None => crate::panic_with_felt252('i128_mul Overflow'),
2380+
}
2381+
}
23702382
}
23712383
}
23722384

‎corelib/src/test/integer_test.cairo‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,11 @@ fn test_i128_operators() {
17631763
@-0x80000000000000000000000000000000_i128,
17641764
'failed MIN_I128 as mul result',
17651765
);
1766+
assert_eq(
1767+
@(1_i128 * 0x7fffffffffffffffffffffffffffffff_i128),
1768+
@0x7fffffffffffffffffffffffffffffff_i128,
1769+
'failed MAX_I128 as mul result',
1770+
);
17661771
assert_lt(1_i128, 4_i128, '1 < 4');
17671772
assert_le(1_i128, 4_i128, '1 <= 4');
17681773
assert(!(4_i128 < 4_i128), '!(4 < 4)');
@@ -1829,23 +1834,29 @@ fn test_i128_add_underflow() {
18291834
}
18301835

18311836
#[test]
1832-
#[should_panic]
1837+
#[should_panic(expected: ('i128_mul Overflow',))]
18331838
fn test_i128_mul_overflow_1() {
18341839
0x10000000000000000000000000000000_i128 * 0x10000000000000000000000000000000_i128;
18351840
}
18361841

18371842
#[test]
1838-
#[should_panic]
1843+
#[should_panic(expected: ('i128_mul Overflow',))]
18391844
fn test_i128_mul_overflow_2() {
18401845
0x11000000000000000000000000000000_i128 * 0x10000000000000000000000000000000_i128;
18411846
}
18421847

18431848
#[test]
1844-
#[should_panic]
1849+
#[should_panic(expected: ('i128_mul Overflow',))]
18451850
fn test_i128_mul_overflow_3() {
18461851
2_i128 * 0x40000000000000000000000000000000_i128;
18471852
}
18481853

1854+
#[test]
1855+
#[should_panic(expected: ('i128_mul Overflow',))]
1856+
fn test_i128_mul_overflow_min_times_minus_one() {
1857+
-0x80000000000000000000000000000000_i128 * -1_i128;
1858+
}
1859+
18491860
#[test]
18501861
#[should_panic(expected: 'attempt to divide with overflow')]
18511862
fn test_i128_divmod_overflow() {

0 commit comments

Comments
 (0)