Skip to content

Commit

Permalink
std::math::big: add the bitwise or operator support to the Int structure
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Mar 10, 2024
1 parent 05a05d6 commit 3bf48fc
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 0 deletions.
8 changes: 8 additions & 0 deletions std/math/big/bits.jule
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ fn sub_res(mut &x: bits, y: bits) {
}
}

// Bitwise or.
// a's bitsize should be have same or greather than b's bitsize.
fn or(mut &a: bits, &b: bits) {
for i in b {
a[i] |= b[i]
}
}

// Update bits by 1's complement.
fn ones_complement(mut &b: bits) {
for i, x in b {
Expand Down
30 changes: 30 additions & 0 deletions std/math/big/int.jule
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,36 @@ impl Int {
}
}

// Bitwise or.
pub fn bit_or(self, y: Int): Int {
let mut r = self
r |= y
ret r
}

// Bitwise or for assignment.
pub fn bit_or_assign(mut self, y: Int) {
if self.len() < y.len() {
let mut xb = make(bits, y.len())
_ = copy(xb, self.nat.bits)
self.nat.bits = xb
}
if self.neg {
twos_complement(self.nat.bits)
}
if y.neg {
twos_complement(y.nat.bits)
}
or(self.nat.bits, y.nat.bits)
if self.neg {
twos_complement(self.nat.bits)
}
if y.neg {
twos_complement(y.nat.bits)
}
self.nat.fit()
}

// Compares bits.
// Returns +1 if self > y.
// Returns 0 if self == y.
Expand Down
25 changes: 25 additions & 0 deletions std/math/big/int_test.jule
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ static cases_int_bit_not: [][]i64 = [
[90, -91],
]

static cases_int_bit_or: [][]i64 = [
[20, 4, 20],
[4, 20, 20],
[345, 2, 347],
[908474739, 747688553334, 748259113847],
[97799739579632223, 1234567890, 97799739731806943],
[-20, 4, -20],
[-4, 20, -4],
[-345, 2, -345],
[-908474739, 747688553334, -570560513],
]

fn test_common_int_op(mut &t: &T, op: str, &cases: [][]str) {
for _, c in cases {
let mut n1 = Int.from_bits(c[0], c[1] == "-") else {
Expand Down Expand Up @@ -148,6 +160,19 @@ fn test_int_bit_not(mut t: &T) {
}
}

#test
fn test_int_bit_or(mut t: &T) {
for _, c in cases_int_bit_or {
let n1 = Int.new(c[0])
let n2 = Int.new(c[1])
let r = n1 | n2
let i = r.to_i64()!
if i != c[2] {
t.errorf("{} | {} != {}", c[0], c[1], c[2])
}
}
}

#test
fn test_int_lt(mut t: &T) {
t.assert(!Int.from_bits("1011010", false)!.lt(Int.from_bits("00001011010", false)!), "1) 1011010 < 00001011010")
Expand Down
17 changes: 17 additions & 0 deletions std/math/big/nat.jule
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,23 @@ impl Nat {
self.bits = self.bits[y:]
}

// Bitwise or.
pub fn bit_or(self, y: Nat): Nat {
let mut r = self
r |= y
ret r
}

// Bitwise or for assignment.
pub fn bit_or_assign(mut self, y: Nat) {
if self.len() < y.len() {
self = y | self
ret
}
self.bits = clone(self.bits)
or(self.bits, y.bits)
}

// Compares bits.
// Returns +1 if self > y.
// Returns 0 if self == y.
Expand Down
21 changes: 21 additions & 0 deletions std/math/big/nat_test.jule
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ static cases_nat_shr: [][]u64 = [
[2, 90, 0],
]

static cases_nat_bit_or: [][]u64 = [
[20, 4, 20],
[4, 20, 20],
[345, 2, 347],
[908474739, 747688553334, 748259113847],
[97799739579632223, 1234567890, 97799739731806943],
]

#test
fn test_nat_from_bits(mut t: &T) {
for _, c in cases_nat_from_bits {
Expand Down Expand Up @@ -181,6 +189,19 @@ fn test_nat_mod(mut t: &T) {
test_common_nat_op(t, "%", cases_nat_mod)
}

#test
fn test_nat_bit_or(mut t: &T) {
for _, c in cases_nat_bit_or {
let n1 = Nat.new(c[0])
let n2 = Nat.new(c[1])
let r = n1 | n2
let u = r.to_u64()!
if u != c[2] {
t.errorf("{} | {} != {}", c[0], c[1], c[2])
}
}
}

#test
fn test_nat_shl(mut t: &T) {
for _, c in cases_nat_shl {
Expand Down

0 comments on commit 3bf48fc

Please sign in to comment.