From 364cd4941969db762a08c005b41078f3a8fc8007 Mon Sep 17 00:00:00 2001 From: Solomon Jackson Date: Wed, 30 Sep 2020 15:15:43 -0400 Subject: [PATCH 1/5] Fix: add % method to BigDecimal --- src/big/big_decimal.cr | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/big/big_decimal.cr b/src/big/big_decimal.cr index 4e23770bf5e3..e8cf1ef21dd8 100644 --- a/src/big/big_decimal.cr +++ b/src/big/big_decimal.cr @@ -189,6 +189,22 @@ struct BigDecimal < Number self * BigDecimal.new(other) end + def %(other : BigDecimal) : BigDecimal + if @scale > other.scale + scaled = other.scale_to(self) + BigDecimal.new(@value % scaled.value, @scale) + elsif @scale < other.scale + scaled = scale_to(other) + BigDecimal.new(scaled.value % other.value, other.scale) + else + BigDecimal.new(@value % other.value, @scale) + end + end + + def %(other : Int) + self % BigDecimal.new(other) + end + def /(other : BigDecimal) : BigDecimal div other end From 8d06816b08c875838fefac7b2155c19bf3f4a33b Mon Sep 17 00:00:00 2001 From: Solomon Jackson Date: Thu, 1 Oct 2020 07:32:40 -0400 Subject: [PATCH 2/5] Add spec for BigDecimal#% --- spec/std/big/big_decimal_spec.cr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/std/big/big_decimal_spec.cr b/spec/std/big/big_decimal_spec.cr index bc62aea6d707..0ba569a4059d 100644 --- a/spec/std/big/big_decimal_spec.cr +++ b/spec/std/big/big_decimal_spec.cr @@ -191,6 +191,8 @@ describe BigDecimal do BigDecimal.new(3333.to_big_i, 7_u64).should eq(BigDecimal.new(1).div(BigDecimal.new(3000), 7)) (-BigDecimal.new(3)).should eq(BigDecimal.new(-3)) + + BigDecimal.new(1).should eq(BigDecimal.new(5) % BigDecimal.new(2)) end it "performs arithmetic with other number types" do From 4210e0890bd586db84f70eea607af074259c3d49 Mon Sep 17 00:00:00 2001 From: Solomon Jackson Date: Thu, 1 Oct 2020 08:41:28 -0400 Subject: [PATCH 3/5] A few more specs for BigDecimal#% --- spec/std/big/big_decimal_spec.cr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/std/big/big_decimal_spec.cr b/spec/std/big/big_decimal_spec.cr index 0ba569a4059d..5b66512a9b46 100644 --- a/spec/std/big/big_decimal_spec.cr +++ b/spec/std/big/big_decimal_spec.cr @@ -192,7 +192,9 @@ describe BigDecimal do (-BigDecimal.new(3)).should eq(BigDecimal.new(-3)) - BigDecimal.new(1).should eq(BigDecimal.new(5) % BigDecimal.new(2)) + (BigDecimal.new(5) % BigDecimal.new(2)).should eq(BigDecimal.new(1)) + (BigDecimal.new(500) % BigDecimal.new(2)).should eq(BigDecimal.new(0)) + (BigDecimal.new(500) % BigDecimal.new(2000)).should eq(BigDecimal.new(500)) end it "performs arithmetic with other number types" do From 7277248aaa166dd7886d179daaf2b66df7e8c32f Mon Sep 17 00:00:00 2001 From: Solomon Jackson Date: Fri, 9 Oct 2020 14:44:29 -0400 Subject: [PATCH 4/5] re-add spec --- spec/std/big/big_decimal_spec.cr | 11 +++++++++++ src/big/big_decimal.cr | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/spec/std/big/big_decimal_spec.cr b/spec/std/big/big_decimal_spec.cr index 5b66512a9b46..466585475364 100644 --- a/spec/std/big/big_decimal_spec.cr +++ b/spec/std/big/big_decimal_spec.cr @@ -387,6 +387,17 @@ describe BigDecimal do bd6.to_f!.should eq -1.1 end + it "handles modulus correctly" do + (BigDecimal.new(13.0) % BigDecimal.new(4.0)).should eq(BigDecimal.new(1.0)) + (BigDecimal.new(13.0) % BigDecimal.new(-4.0)).should eq(BigDecimal.new(-3.0)) + (BigDecimal.new(-13.0) % BigDecimal.new(4.0)).should eq(BigDecimal.new(3.0)) + (BigDecimal.new(-13.0) % BigDecimal.new(-4.0)).should eq(BigDecimal.new(-1.0)) + (BigDecimal.new(11.5) % BigDecimal.new(4.0)).should eq(BigDecimal.new(3.5)) + (BigDecimal.new(11.5) % BigDecimal.new(-4.0)).should eq(BigDecimal.new(-0.5)) + (BigDecimal.new(-11.5) % BigDecimal.new(4.0)).should eq(BigDecimal.new(0.5)) + (BigDecimal.new(-11.5) % BigDecimal.new(-4.0)).should eq(BigDecimal.new(-3.5)) +end + it "hashes" do bd1 = BigDecimal.new("123.456") bd2 = BigDecimal.new("0.12345") diff --git a/src/big/big_decimal.cr b/src/big/big_decimal.cr index e8cf1ef21dd8..7bf14171f4c4 100644 --- a/src/big/big_decimal.cr +++ b/src/big/big_decimal.cr @@ -305,6 +305,10 @@ struct BigDecimal < Number BigDecimal.new(@value ** other, @scale * other) end + def **(other : BigDecimal) : BigDecimal + self ** other.value + end + def ceil : BigDecimal mask = power_ten_to(@scale) diff = (mask - @value % mask) % mask From 3022c838a3eabd487b2de4d4534cdc2f63ecb408 Mon Sep 17 00:00:00 2001 From: Solomon Jackson Date: Tue, 13 Oct 2020 17:25:28 -0400 Subject: [PATCH 5/5] make ci happy *sigh* --- spec/std/big/big_decimal_spec.cr | 2 +- src/big/big_decimal.cr | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/spec/std/big/big_decimal_spec.cr b/spec/std/big/big_decimal_spec.cr index 466585475364..3042612f6dff 100644 --- a/spec/std/big/big_decimal_spec.cr +++ b/spec/std/big/big_decimal_spec.cr @@ -396,7 +396,7 @@ describe BigDecimal do (BigDecimal.new(11.5) % BigDecimal.new(-4.0)).should eq(BigDecimal.new(-0.5)) (BigDecimal.new(-11.5) % BigDecimal.new(4.0)).should eq(BigDecimal.new(0.5)) (BigDecimal.new(-11.5) % BigDecimal.new(-4.0)).should eq(BigDecimal.new(-3.5)) -end + end it "hashes" do bd1 = BigDecimal.new("123.456") diff --git a/src/big/big_decimal.cr b/src/big/big_decimal.cr index 7bf14171f4c4..e8cf1ef21dd8 100644 --- a/src/big/big_decimal.cr +++ b/src/big/big_decimal.cr @@ -305,10 +305,6 @@ struct BigDecimal < Number BigDecimal.new(@value ** other, @scale * other) end - def **(other : BigDecimal) : BigDecimal - self ** other.value - end - def ceil : BigDecimal mask = power_ten_to(@scale) diff = (mask - @value % mask) % mask