Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
gaetbout committed Jul 24, 2024
1 parent c17e14d commit 081df79
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 63 deletions.
8 changes: 4 additions & 4 deletions packages/math/src/bitmap.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub impl Bitmap<
#[inline(always)]
fn nearest_left_significant_bit(x: T, i: u8) -> Option::<u8> {
let mask = ~(pow(2_u8.into(), i.into()) - 1_u8.into());
Bitmap::least_significant_bit(x & mask)
Self::least_significant_bit(x & mask)
}

/// The index of the nearest right significant bit to the index of a number.
Expand All @@ -178,7 +178,7 @@ pub impl Bitmap<
#[inline(always)]
fn nearest_right_significant_bit(x: T, i: u8) -> Option::<u8> {
let mask = pow(2_u8.into(), (i + 1).into()) - 1_u8.into();
Bitmap::most_significant_bit(x & mask)
Self::most_significant_bit(x & mask)
}

/// The index of the nearest significant bit to the index of a number,
Expand All @@ -192,8 +192,8 @@ pub impl Bitmap<
/// * The index of the nearest significant bit, None is returned if no significant bit is found.
#[inline(always)]
fn nearest_significant_bit(x: T, i: u8, priority: bool) -> Option::<u8> {
let nlsb = Bitmap::nearest_left_significant_bit(x, i);
let nrsb = Bitmap::nearest_right_significant_bit(x, i);
let nlsb = Self::nearest_left_significant_bit(x, i);
let nrsb = Self::nearest_right_significant_bit(x, i);
match (nlsb, nrsb) {
(
Option::Some(lhs), Option::Some(rhs)
Expand Down
7 changes: 4 additions & 3 deletions packages/math/src/extended_euclidean_algorithm.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! # Extended Euclidean Algorithm.
use core::integer::{u128_overflowing_sub, u128_overflowing_mul, u128_wrapping_sub};
use core::num::traits::{OverflowingMul, OverflowingSub};

/// Extended Euclidean Algorithm.
/// # Arguments
Expand Down Expand Up @@ -31,8 +31,9 @@ pub fn extended_euclidean_algorithm(a: u128, b: u128) -> (u128, u128, u128) {
/// Update the step of the extended Euclidean algorithm.
fn update_step(ref a: u128, ref old_a: u128, quotient: u128) {
let temp = a;
let (bottom, _) = u128_overflowing_mul(quotient, temp);
a = u128_wrapping_sub(old_a, bottom);
let (bottom, _) = quotient.overflowing_mul(temp);
let (a_tmp, _) = old_a.overflowing_sub(bottom);
a = a_tmp;
old_a = temp;
}

40 changes: 21 additions & 19 deletions packages/math/src/i257.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use core::num::traits::Zero;
use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};

// ====================== INT 257 ======================

// i257 represents a 129-bit integer.
Expand Down Expand Up @@ -61,10 +63,10 @@ impl i257Add of Add<i257> {
}

// Implements the AddEq trait for i257.
impl i257AddEq of AddEq<i257> {
impl i257AddEq of AddAssign<i257, i257> {
#[inline(always)]
fn add_eq(ref self: i257, other: i257) {
self = Add::add(self, other);
fn add_assign(ref self: i257, rhs: i257) {
self = Add::add(self, rhs);
}
}

Expand All @@ -86,10 +88,10 @@ impl i257Sub of Sub<i257> {
}

// Implements the SubEq trait for i257.
impl i257SubEq of SubEq<i257> {
impl i257SubEq of SubAssign<i257, i257> {
#[inline(always)]
fn sub_eq(ref self: i257, other: i257) {
self = Sub::sub(self, other);
fn sub_assign(ref self: i257, rhs: i257) {
self = Sub::sub(self, rhs);
}
}

Expand All @@ -108,10 +110,10 @@ impl i257Mul of Mul<i257> {
}

// Implements the MulEq trait for i257.
impl i257MulEq of MulEq<i257> {
impl i257MulEq of MulAssign<i257, i257> {
#[inline(always)]
fn mul_eq(ref self: i257, other: i257) {
self = Mul::mul(self, other);
fn mul_assign(ref self: i257, rhs: i257) {
self = Mul::mul(self, rhs);
}
}

Expand Down Expand Up @@ -161,10 +163,10 @@ impl i257Div of Div<i257> {
}

// Implements the DivEq trait for i257.
impl i257DivEq of DivEq<i257> {
impl i257DivEq of DivAssign<i257, i257> {
#[inline(always)]
fn div_eq(ref self: i257, other: i257) {
self = Div::div(self, other);
fn div_assign(ref self: i257, rhs: i257) {
self = Div::div(self, rhs);
}
}

Expand All @@ -189,10 +191,10 @@ impl i257Rem of Rem<i257> {
}

// Implements the RemEq trait for i257.
impl i257RemEq of RemEq<i257> {
impl i257RemEq of RemAssign<i257, i257> {
#[inline(always)]
fn rem_eq(ref self: i257, other: i257) {
self = Rem::rem(self, other);
fn rem_assign(ref self: i257, rhs: i257) {
self = Rem::rem(self, rhs);
}
}

Expand All @@ -219,7 +221,7 @@ impl i257PartialEq of PartialEq<i257> {
}

fn ne(lhs: @i257, rhs: @i257) -> bool {
!i257PartialEq::eq(lhs, rhs)
!Self::eq(lhs, rhs)
}
}

Expand All @@ -228,14 +230,14 @@ impl i257PartialEq of PartialEq<i257> {
// Ensure that neither `lhs` nor `rhs` is negative zero before calling.
impl i257PartialOrd of PartialOrd<i257> {
fn le(lhs: i257, rhs: i257) -> bool {
!i257PartialOrd::gt(lhs, rhs)
!Self::gt(lhs, rhs)
}
fn ge(lhs: i257, rhs: i257) -> bool {
i257PartialOrd::gt(lhs, rhs) || lhs == rhs
Self::gt(lhs, rhs) || lhs == rhs
}

fn lt(lhs: i257, rhs: i257) -> bool {
!i257PartialOrd::gt(lhs, rhs) && lhs != rhs
!Self::gt(lhs, rhs) && lhs != rhs
}

fn gt(lhs: i257, rhs: i257) -> bool {
Expand Down
27 changes: 11 additions & 16 deletions packages/math/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ pub mod trigonometry;
pub mod u512_arithmetics;
pub mod wad_ray_math;
pub mod zellers_congruence;
use core::integer::{
u8_wide_mul, u16_wide_mul, u32_wide_mul, u64_wide_mul, u128_wide_mul, BoundedInt,
u256_overflow_mul
};
use core::integer::BoundedInt;
use core::num::traits::{WrappingAdd, WrappingSub, WrappingMul, WideMul, OverflowingMul};

/// Raise a number to a power.
Expand Down Expand Up @@ -73,7 +70,7 @@ pub trait BitShift<T> {

pub impl U8BitShift of BitShift<u8> {
fn shl(x: u8, n: u8) -> u8 {
(u8_wide_mul(x, pow(2, n)) & BoundedInt::<u8>::max().into()).try_into().unwrap()
(WideMul::wide_mul(x, pow(2, n)) & BoundedInt::<u8>::max().into()).try_into().unwrap()
}

fn shr(x: u8, n: u8) -> u8 {
Expand All @@ -83,7 +80,7 @@ pub impl U8BitShift of BitShift<u8> {

pub impl U16BitShift of BitShift<u16> {
fn shl(x: u16, n: u16) -> u16 {
(u16_wide_mul(x, pow(2, n)) & BoundedInt::<u16>::max().into()).try_into().unwrap()
(WideMul::wide_mul(x, pow(2, n)) & BoundedInt::<u16>::max().into()).try_into().unwrap()
}

fn shr(x: u16, n: u16) -> u16 {
Expand All @@ -93,7 +90,7 @@ pub impl U16BitShift of BitShift<u16> {

pub impl U32BitShift of BitShift<u32> {
fn shl(x: u32, n: u32) -> u32 {
(u32_wide_mul(x, pow(2, n)) & BoundedInt::<u32>::max().into()).try_into().unwrap()
(WideMul::wide_mul(x, pow(2, n)) & BoundedInt::<u32>::max().into()).try_into().unwrap()
}

fn shr(x: u32, n: u32) -> u32 {
Expand All @@ -103,7 +100,7 @@ pub impl U32BitShift of BitShift<u32> {

pub impl U64BitShift of BitShift<u64> {
fn shl(x: u64, n: u64) -> u64 {
(u64_wide_mul(x, pow(2, n)) & BoundedInt::<u64>::max().into()).try_into().unwrap()
(WideMul::wide_mul(x, pow(2, n)) & BoundedInt::<u64>::max().into()).try_into().unwrap()
}

fn shr(x: u64, n: u64) -> u64 {
Expand All @@ -113,8 +110,7 @@ pub impl U64BitShift of BitShift<u64> {

pub impl U128BitShift of BitShift<u128> {
fn shl(x: u128, n: u128) -> u128 {
let (_, bottom_word) = u128_wide_mul(x, pow(2, n));
bottom_word
WideMul::wide_mul(x, pow(2, n)).low
}

fn shr(x: u128, n: u128) -> u128 {
Expand Down Expand Up @@ -154,7 +150,7 @@ trait BitRotate<T> {

pub impl U8BitRotate of BitRotate<u8> {
fn rotate_left(x: u8, n: u8) -> u8 {
let word = u8_wide_mul(x, pow(2, n));
let word = WideMul::wide_mul(x, pow(2, n));
let (quotient, remainder) = DivRem::div_rem(word, 0x100_u16.try_into().unwrap());
(quotient + remainder).try_into().unwrap()
}
Expand All @@ -168,7 +164,7 @@ pub impl U8BitRotate of BitRotate<u8> {

pub impl U16BitRotate of BitRotate<u16> {
fn rotate_left(x: u16, n: u16) -> u16 {
let word = u16_wide_mul(x, pow(2, n));
let word = WideMul::wide_mul(x, pow(2, n));
let (quotient, remainder) = DivRem::div_rem(word, 0x10000_u32.try_into().unwrap());
(quotient + remainder).try_into().unwrap()
}
Expand All @@ -182,7 +178,7 @@ pub impl U16BitRotate of BitRotate<u16> {

pub impl U32BitRotate of BitRotate<u32> {
fn rotate_left(x: u32, n: u32) -> u32 {
let word = u32_wide_mul(x, pow(2, n));
let word = WideMul::wide_mul(x, pow(2, n));
let (quotient, remainder) = DivRem::div_rem(word, 0x100000000_u64.try_into().unwrap());
(quotient + remainder).try_into().unwrap()
}
Expand All @@ -196,7 +192,7 @@ pub impl U32BitRotate of BitRotate<u32> {

pub impl U64BitRotate of BitRotate<u64> {
fn rotate_left(x: u64, n: u64) -> u64 {
let word = u64_wide_mul(x, pow(2, n));
let word = WideMul::wide_mul(x, pow(2, n));
let (quotient, remainder) = DivRem::div_rem(
word, 0x10000000000000000_u128.try_into().unwrap()
);
Expand All @@ -212,8 +208,7 @@ pub impl U64BitRotate of BitRotate<u64> {

pub impl U128BitRotate of BitRotate<u128> {
fn rotate_left(x: u128, n: u128) -> u128 {
let (high, low) = u128_wide_mul(x, pow(2, n));
let word = u256 { low, high };
let word = WideMul::wide_mul(x, pow(2, n));
let (quotient, remainder) = DivRem::div_rem(
word, u256 { low: 0, high: 1 }.try_into().unwrap()
);
Expand Down
50 changes: 29 additions & 21 deletions packages/math/src/u512_arithmetics.cairo
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
use core::integer::u512;
use core::integer::{u128_overflowing_add, u128_overflowing_sub};
use core::num::traits::{OverflowingAdd, OverflowingSub};
use core::result::ResultTrait;

pub fn u256_overflow_add(lhs: u256, rhs: u256) -> Result<u256, u256> implicits(RangeCheck) nopanic {
let (sum, overflow) = core::integer::u256_overflowing_add(lhs, rhs);
// TODO Say deprecated and use
// use core::num::traits::{OverflowingAdd, OverflowingSub};
pub fn u256_overflow_add(lhs: u256, rhs: u256) -> Result<u256, u256> implicits(RangeCheck) {
let (sum, overflow) = lhs.overflowing_add(rhs);
if overflow {
Result::Err(sum)
} else {
Result::Ok(sum)
}
}

pub fn u256_overflow_sub(lhs: u256, rhs: u256) -> Result<u256, u256> implicits(RangeCheck) nopanic {
let (sum, overflow) = core::integer::u256_overflow_sub(lhs, rhs);
pub fn u256_overflow_sub(lhs: u256, rhs: u256) -> Result<u256, u256> implicits(RangeCheck) {
let (sum, overflow) = lhs.overflowing_sub(rhs);
if overflow {
Result::Err(sum)
} else {
Expand Down Expand Up @@ -48,14 +50,17 @@ pub fn u512_add(lhs: u512, rhs: u512) -> u512 {
Result::Err(u256 { low: limb0,
high: limb1 }) => {
// Try to move overflow to limb2
return match u128_overflowing_add(limb2, 1_u128) {
Result::Ok(limb2) => u512 { limb0, limb1, limb2, limb3 },
Result::Err(limb2) => {
// Try to move overflow to limb3
let limb3 = u128_overflowing_add(limb3, 1_u128).expect('u512 add overflow');
u512 { limb0, limb1, limb2, limb3 }
},
};
let (limb2, did_overflow) = limb2.overflowing_add(1_u128);
if did_overflow {
// Try to move overflow to limb3
let (limb3, did_overflow) = limb3.overflowing_add(1_u128);
if did_overflow {
panic!("u512 add overflow");
}
u512 { limb0, limb1, limb2, limb3 }
} else {
u512 { limb0, limb1, limb2, limb3 }
}
},
}
}
Expand All @@ -74,14 +79,17 @@ pub fn u512_sub(lhs: u512, rhs: u512) -> u512 {
Result::Err(u256 { low: limb0,
high: limb1 }) => {
// Try to move overflow to limb2
return match u128_overflowing_sub(limb2, 1_u128) {
Result::Ok(limb2) => u512 { limb0, limb1, limb2, limb3 },
Result::Err(limb2) => {
// Try to move overflow to limb3
let limb3 = u128_overflowing_sub(limb3, 1_u128).expect('u512 sub overflow');
u512 { limb0, limb1, limb2, limb3 }
},
};
let (limb2, did_overflow) = limb2.overflowing_sub(1_u128);
if did_overflow {
// Try to move overflow to limb3
let (limb3, did_overflow) = limb3.overflowing_sub(1_u128);
if did_overflow {
panic!("u512 sub overflow");
}
u512 { limb0, limb1, limb2, limb3 }
} else {
u512 { limb0, limb1, limb2, limb3 }
}
},
}
}

0 comments on commit 081df79

Please sign in to comment.