From fdfe09326998601b623bf73fdede4ecc1008e53f Mon Sep 17 00:00:00 2001 From: "bob.hongbo.zhang" Date: Thu, 29 Aug 2024 20:07:48 +0800 Subject: [PATCH 1/5] try to make sharing --- builtin/bigint.mbt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builtin/bigint.mbt b/builtin/bigint.mbt index db5486261..cab98b00c 100644 --- a/builtin/bigint.mbt +++ b/builtin/bigint.mbt @@ -61,9 +61,9 @@ let karatsuba_threshold = 50 // Useful bigints -let zero : BigInt = 0N +let zero : BigInt = { limbs: [0], sign: Positive, len: 1 } -let one : BigInt = 1N +let one : BigInt = { limbs: [1], sign: Positive, len: 1 } // Conversion Functions @@ -75,7 +75,7 @@ pub fn BigInt::from_int(n : Int) -> BigInt { /// Convert an Int64 to a BigInt. pub fn BigInt::from_int64(n : Int64) -> BigInt { if n == 0L { - return { limbs: FixedArray::make(1, 0), sign: Positive, len: 1 } + return zero } let limbs = FixedArray::make(64 / radix_bit_len, 0) let mut m = if n < 0L { -n } else { n } From f04f95b21ff7351be0fca062963106e6534addc2 Mon Sep 17 00:00:00 2001 From: "bob.hongbo.zhang" Date: Thu, 29 Aug 2024 20:11:46 +0800 Subject: [PATCH 2/5] add BigInt::equal_int BigInt::equal_int64 --- builtin/bigint.mbt | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/builtin/bigint.mbt b/builtin/bigint.mbt index cab98b00c..7f6353678 100644 --- a/builtin/bigint.mbt +++ b/builtin/bigint.mbt @@ -72,6 +72,75 @@ pub fn BigInt::from_int(n : Int) -> BigInt { BigInt::from_int64(n.to_int64()) } +pub fn BigInt::equal_int64(self : BigInt, n : Int64) -> Bool { + // Check if the sign of BigInt matches the sign of n + if (self.sign == Negative && n >= 0) || (self.sign == Positive && n < 0) { + return false + } + + // Handle zero case + if n == 0L { + return self.is_zero() + } + + // Convert n to positive for comparison + let mut m = if n < 0L { -n } else { n } + let mut i = 0 + + // Compare limbs + while m > 0L { + if i >= self.len || self.limbs[i] != (m % radix).to_int() { + return false + } + m /= radix + i += 1 + } + + // Ensure all remaining limbs in BigInt are zero + while i < self.len { + if self.limbs[i] != 0 { + return false + } + i += 1 + } + true +} + +pub fn BigInt::equal_int(self : BigInt, other : Int) -> Bool { + // Check if the sign of BigInt matches the sign of other + if (self.sign == Negative && other >= 0) || + (self.sign == Positive && other < 0) { + return false + } + + // Handle zero case + if other == 0 { + return self.is_zero() + } + + // Convert other to positive for comparison + let mut m = if other < 0 { -other } else { other } + let mut i = 0 + + // Compare limbs + while m > 0 { + if i >= self.len || self.limbs[i] != m % radix.to_int() { + return false + } + m /= radix.to_int() + i += 1 + } + + // Ensure all remaining limbs in BigInt are zero + while i < self.len { + if self.limbs[i] != 0 { + return false + } + i += 1 + } + true +} + /// Convert an Int64 to a BigInt. pub fn BigInt::from_int64(n : Int64) -> BigInt { if n == 0L { From 2d70056e4fb583d2369ce2e44dbffcb9159b4eb6 Mon Sep 17 00:00:00 2001 From: "bob.hongbo.zhang" Date: Thu, 29 Aug 2024 20:13:13 +0800 Subject: [PATCH 3/5] add tests --- builtin/bigint_wbtest.mbt | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/builtin/bigint_wbtest.mbt b/builtin/bigint_wbtest.mbt index f22dd2469..73b2b3175 100644 --- a/builtin/bigint_wbtest.mbt +++ b/builtin/bigint_wbtest.mbt @@ -20,6 +20,47 @@ impl Show for MyBigInt with output(self, logger) { ) } +test { + inspect!( + MyBigInt(BigInt::from_int64(0)), + content="{limbs : [0], sign : Positive, len : 1 }", + ) + inspect!( + MyBigInt(BigInt::from_int64(1)), + content="{limbs : [1, 0, 0, 0], sign : Positive, len : 1 }", + ) + inspect!(MyBigInt(1), content="{limbs : [1, 0], sign : Positive, len : 1 }") + inspect!( + MyBigInt(0xffff_ffff), + content="{limbs : [65535, 65535, 0, 0], sign : Positive, len : 2 }", + ) + inspect!( + MyBigInt(0xffff_ffff_ffff_ffff), + content="{limbs : [65535, 65535, 65535, 65535, 0, 0], sign : Positive, len : 4 }", + ) +} + +test "equal_int64" { + assert_eq!(BigInt::from_int64(0).equal_int64(0), true) + assert_eq!(BigInt::from_int64(1).equal_int64(1), true) + assert_eq!(BigInt::from_int64(0xffff_ffff).equal_int64(0xffff_ffff), true) + inspect!(BigInt::from_int64(0xffff_ffff_ffff_ffff), content="-1") + inspect!((0xffff_ffff_ffff_ffffN), content="18446744073709551615") + assert_eq!( + BigInt::from_int64(0xffff_ffff_ffff_ffff).equal_int64(0xffff_ffff_ffff_ffff), + true, + ) +} + +test "equal_int" { + assert_eq!(BigInt::from_int64(0).equal_int(0), true) + assert_eq!(BigInt::from_int64(1).equal_int(1), true) + // overflow + assert_eq!(BigInt::from_int64(0xffff_ffff).equal_int(0xffff_ffff), false) + assert_eq!(BigInt::from_int64(0x7fff_ffff).equal_int(0x7fff_ffff), true) + assert_eq!(BigInt::from_int64(0x8fff_ffff).equal_int(0x8fff_ffff), false) +} + test "debug_string" { let buf = Buffer::new() let v : Array[MyBigInt] = [0, 1, 2, 3, 4, -0, -1, -2, -3] From 87eef99c7fd43776acc524e26ed1665032efd72e Mon Sep 17 00:00:00 2001 From: "bob.hongbo.zhang" Date: Thu, 29 Aug 2024 20:13:26 +0800 Subject: [PATCH 4/5] info --- builtin/builtin.mbti | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builtin/builtin.mbti b/builtin/builtin.mbti index 527cfad4c..54675dd3f 100644 --- a/builtin/builtin.mbti +++ b/builtin/builtin.mbti @@ -128,6 +128,8 @@ type BigInt impl BigInt { asr(Self, Int) -> Self compare(Self, Self) -> Int + equal_int(Self, Int) -> Bool + equal_int64(Self, Int64) -> Bool from_hex(String) -> Self from_int(Int) -> Self from_int64(Int64) -> Self From 9f98d079f380a73b3612edcf5c8200d8b3a499f2 Mon Sep 17 00:00:00 2001 From: "bob.hongbo.zhang" Date: Thu, 29 Aug 2024 20:14:55 +0800 Subject: [PATCH 5/5] fmt --- builtin/bigint_wbtest.mbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/bigint_wbtest.mbt b/builtin/bigint_wbtest.mbt index 73b2b3175..cd612f5ad 100644 --- a/builtin/bigint_wbtest.mbt +++ b/builtin/bigint_wbtest.mbt @@ -45,7 +45,7 @@ test "equal_int64" { assert_eq!(BigInt::from_int64(1).equal_int64(1), true) assert_eq!(BigInt::from_int64(0xffff_ffff).equal_int64(0xffff_ffff), true) inspect!(BigInt::from_int64(0xffff_ffff_ffff_ffff), content="-1") - inspect!((0xffff_ffff_ffff_ffffN), content="18446744073709551615") + inspect!(0xffff_ffff_ffff_ffffN, content="18446744073709551615") assert_eq!( BigInt::from_int64(0xffff_ffff_ffff_ffff).equal_int64(0xffff_ffff_ffff_ffff), true,