Skip to content

Commit

Permalink
Add BigRational#%, #tdiv, #remainder (#14306)
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil authored Feb 21, 2024
1 parent 9291ea4 commit 9866e50
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 4 deletions.
72 changes: 68 additions & 4 deletions spec/std/big/big_rational_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,74 @@ describe BigRational do
end

it "#//" do
(br(10, 7) // br(3, 7)).should eq(br(9, 3))
expect_raises(DivisionByZeroError) { br(10, 7) / br(0, 10) }
(br(10, 7) // 3).should eq(0)
(1 // br(10, 7)).should eq(0)
(br(18, 7) // br(4, 5)).should eq(br(3, 1))
(br(-18, 7) // br(4, 5)).should eq(br(-4, 1))
(br(18, 7) // br(-4, 5)).should eq(br(-4, 1))
(br(-18, 7) // br(-4, 5)).should eq(br(3, 1))

(br(18, 5) // 2).should eq(br(1, 1))
(br(-18, 5) // 2).should eq(br(-2, 1))
(br(18, 5) // -2).should eq(br(-2, 1))
(br(-18, 5) // -2).should eq(br(1, 1))
(br(18, 5) // 2.to_big_i).should eq(br(1, 1))

expect_raises(DivisionByZeroError) { br(18, 7) // br(0, 1) }
expect_raises(DivisionByZeroError) { br(18, 7) // 0 }

(8 // br(10, 7)).should eq(5)
(-8 // br(10, 7)).should eq(-6)
(8 // br(-10, 7)).should eq(-6)
(-8 // br(-10, 7)).should eq(5)

expect_raises(DivisionByZeroError) { 8 // br(0, 7) }
end

it "#%" do
(br(18, 7) % br(4, 5)).should eq(br(6, 35))
(br(-18, 7) % br(4, 5)).should eq(br(22, 35))
(br(18, 7) % br(-4, 5)).should eq(br(-22, 35))
(br(-18, 7) % br(-4, 5)).should eq(br(-6, 35))

(br(18, 5) % 2).should eq(br(8, 5))
(br(-18, 5) % 2).should eq(br(2, 5))
(br(18, 5) % -2).should eq(br(-2, 5))
(br(-18, 5) % -2).should eq(br(-8, 5))
(br(18, 5) % 2.to_big_i).should eq(br(8, 5))

expect_raises(DivisionByZeroError) { br(18, 7) % br(0, 1) }
expect_raises(DivisionByZeroError) { br(18, 7) % 0 }
end

it "#tdiv" do
br(18, 7).tdiv(br(4, 5)).should eq(br(3, 1))
br(-18, 7).tdiv(br(4, 5)).should eq(br(-3, 1))
br(18, 7).tdiv(br(-4, 5)).should eq(br(-3, 1))
br(-18, 7).tdiv(br(-4, 5)).should eq(br(3, 1))

br(18, 5).tdiv(2).should eq(br(1, 1))
br(-18, 5).tdiv(2).should eq(br(-1, 1))
br(18, 5).tdiv(-2).should eq(br(-1, 1))
br(-18, 5).tdiv(-2).should eq(br(1, 1))
br(18, 5).tdiv(2.to_big_i).should eq(br(1, 1))

expect_raises(DivisionByZeroError) { br(18, 7).tdiv(br(0, 1)) }
expect_raises(DivisionByZeroError) { br(18, 7).tdiv(0) }
end

it "#remainder" do
br(18, 7).remainder(br(4, 5)).should eq(br(6, 35))
br(-18, 7).remainder(br(4, 5)).should eq(br(-6, 35))
br(18, 7).remainder(br(-4, 5)).should eq(br(6, 35))
br(-18, 7).remainder(br(-4, 5)).should eq(br(-6, 35))

br(18, 5).remainder(2).should eq(br(8, 5))
br(-18, 5).remainder(2).should eq(br(-8, 5))
br(18, 5).remainder(-2).should eq(br(8, 5))
br(-18, 5).remainder(-2).should eq(br(-8, 5))
br(18, 5).remainder(2.to_big_i).should eq(br(8, 5))

expect_raises(DivisionByZeroError) { br(18, 7).remainder(br(0, 1)) }
expect_raises(DivisionByZeroError) { br(18, 7).remainder(0) }
end

it "#- (negation)" do
Expand Down
46 changes: 46 additions & 0 deletions src/big/big_rational.cr
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,52 @@ struct BigRational < Number

Number.expand_div [BigInt, BigFloat, BigDecimal], BigRational

def //(other : BigRational) : BigRational
check_division_by_zero other
BigRational.new((numerator * other.denominator) // (denominator * other.numerator))
end

def //(other : Int) : BigRational
check_division_by_zero other
BigRational.new(numerator // (denominator * other))
end

def %(other : BigRational) : BigRational
check_division_by_zero other
BigRational.new(
(numerator * other.denominator) % (denominator * other.numerator),
denominator * other.denominator,
)
end

def %(other : Int) : BigRational
check_division_by_zero other
BigRational.new(numerator % (denominator * other), denominator)
end

def tdiv(other : BigRational) : BigRational
check_division_by_zero other
BigRational.new((numerator * other.denominator).tdiv(denominator * other.numerator))
end

def tdiv(other : Int) : BigRational
check_division_by_zero other
BigRational.new(numerator.tdiv(denominator * other))
end

def remainder(other : BigRational) : BigRational
check_division_by_zero other
BigRational.new(
(numerator * other.denominator).remainder(denominator * other.numerator),
denominator * other.denominator,
)
end

def remainder(other : Int) : BigRational
check_division_by_zero other
BigRational.new(numerator.remainder(denominator * other), denominator)
end

def ceil : BigRational
BigRational.new(-(-numerator // denominator))
end
Expand Down

0 comments on commit 9866e50

Please sign in to comment.