diff --git a/spec/std/big/big_decimal_spec.cr b/spec/std/big/big_decimal_spec.cr index dc73671ec3f9..c6c7e45a6225 100644 --- a/spec/std/big/big_decimal_spec.cr +++ b/spec/std/big/big_decimal_spec.cr @@ -277,6 +277,14 @@ describe BigDecimal do end end + describe ".with_rounding_mode" do + it "sets given mode as .rounding_mode within yielded block" do + BigDecimal.with_rounding_mode(:half_even) do + BigDecimal.rounding_mode.should eq(BigDecimal::RoundingMode::HALF_EVEN) + end + end + end + it "performs arithmetic with other number types" do (1.to_big_d + 2).should eq(BigDecimal.new("3.0")) (2 + 1.to_big_d).should eq(BigDecimal.new("3.0")) diff --git a/src/big/big_decimal.cr b/src/big/big_decimal.cr index eb3eb1c7b72e..d0ef9cb4f8f0 100644 --- a/src/big/big_decimal.cr +++ b/src/big/big_decimal.cr @@ -286,6 +286,28 @@ struct BigDecimal < Number end end + # Executes the provided block, preserving the rounding mode; *mode* argument + # is set as `BigDecimal.rounding_mode` inside the block. + # + # ``` + # BigDecimal.rounding_mode = :half_even + # + # # *mode* argument is set as `BigDecimal.rounding_mode` inside the block + # BigDecimal.with_rounding_mode(:up) do + # BigDecimal.rounding_mode # => BigDecimal::RoundingMode::UP + # end + # + # BigDecimal.rounding_mode # => BigDecimal::RoundingMode::HALF_EVEN + # ``` + # + # NOTE: Uses `save_rounding_mode` internally. + def self.with_rounding_mode(mode : RoundingMode?) + save_rounding_mode do + @@rounding_mode = mode + yield + end + end + # Rounds to the nearest integer (by default), returning the result as a `BigDecimal`. # # ```