Skip to content

Commit

Permalink
Optimize BigInt#bit
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil committed Nov 14, 2023
1 parent 3a83996 commit 3106678
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
28 changes: 28 additions & 0 deletions spec/std/big/big_int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,34 @@ describe "BigInt" do
-5.to_big_i.remainder(-3).should eq(-2)
end

it "#bit" do
x = 123.to_big_i
x.bit(-10.to_big_i ** 99).should eq(0)
x.bit(-(2.to_big_i ** 64)).should eq(0)
x.bit(-1).should eq(0)
x.bit(0).should eq(1)
x.bit(2).should eq(0)
x.bit(3).should eq(1)
x.bit(6).should eq(1)
x.bit(7).should eq(0)
x.bit(64).should eq(0)
x.bit(2.to_big_i ** 64).should eq(0)
x.bit(10.to_big_i ** 99).should eq(0)

x = ~(123.to_big_i)
x.bit(-10.to_big_i ** 99).should eq(0)
x.bit(-(2.to_big_i ** 64)).should eq(0)
x.bit(-1).should eq(0)
x.bit(0).should eq(0)
x.bit(2).should eq(1)
x.bit(3).should eq(0)
x.bit(6).should eq(0)
x.bit(7).should eq(1)
x.bit(64).should eq(1)
x.bit(2.to_big_i ** 64).should eq(1)
x.bit(10.to_big_i ** 99).should eq(1)
end

it "does bitwise and" do
(123.to_big_i & 321).should eq(65)
(BigInt.new("96238761238973286532") & 86325735648).should eq(69124358272)
Expand Down
6 changes: 6 additions & 0 deletions src/big/big_int.cr
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,12 @@ struct BigInt < Int
BigInt.new { |mpz| LibGMP.com(mpz, self) }
end

def bit(bit : Int)
return 0 if bit < 0
return self < 0 ? 1 : 0 if bit > LibGMP::BitcntT::MAX
LibGMP.tstbit(self, LibGMP::BitcntT.new!(bit))
end

def &(other : Int) : BigInt
BigInt.new { |mpz| LibGMP.and(mpz, self, other.to_big_i) }
end
Expand Down
2 changes: 2 additions & 0 deletions src/big/lib_gmp.cr
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ lib LibGMP
fun xor = __gmpz_xor(rop : MPZ*, op1 : MPZ*, op2 : MPZ*)
fun com = __gmpz_com(rop : MPZ*, op : MPZ*)

fun tstbit = __gmpz_tstbit(op : MPZ*, bit_index : BitcntT) : Int

fun fdiv_q_2exp = __gmpz_fdiv_q_2exp(q : MPZ*, n : MPZ*, b : BitcntT)
fun mul_2exp = __gmpz_mul_2exp(rop : MPZ*, op1 : MPZ*, op2 : BitcntT)

Expand Down

0 comments on commit 3106678

Please sign in to comment.