From 8cdf5cd55f6fbfa3151fdd1e1fd895080cea66d9 Mon Sep 17 00:00:00 2001 From: Maciej Rzasa Date: Tue, 4 Feb 2025 23:55:45 +0100 Subject: [PATCH 1/3] Allow BigDecimal accept Float without precision --- ext/bigdecimal/bigdecimal.c | 12 ++++-------- test/bigdecimal/test_bigdecimal.rb | 7 ++++--- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index a707295e..dda56e6e 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -3458,11 +3458,7 @@ rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) } if (digs == SIZE_MAX) { - if (!raise_exception) - return Qnil; - rb_raise(rb_eArgError, - "can't omit precision for a %"PRIsVALUE".", - CLASS_OF(val)); + digs = 0; } else if (digs > BIGDECIMAL_DOUBLE_FIGURES) { if (!raise_exception) @@ -3712,12 +3708,12 @@ rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) * * - Integer, Float, Rational, Complex, or BigDecimal: converted directly: * - * # Integer, Complex, or BigDecimal value does not require ndigits; ignored if given. + * # Integer, Complex, Float, or BigDecimal value does not require ndigits; ignored if given. * BigDecimal(2) # => 0.2e1 * BigDecimal(Complex(2, 0)) # => 0.2e1 * BigDecimal(BigDecimal(2)) # => 0.2e1 - * # Float or Rational value requires ndigits. - * BigDecimal(2.0, 0) # => 0.2e1 + * BigDecimal(2.0) # => 0.2e1 + * # Rational value requires ndigits. * BigDecimal(Rational(2, 1), 0) # => 0.2e1 * * - String: converted by parsing if it contains an integer or floating-point literal; diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index fab9622a..1ceae553 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -166,7 +166,8 @@ def test_BigDecimal_with_float assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4)) assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4)) assert_equal(BigDecimal("0.01"), BigDecimal(0.01, Float::DIG + 1)) - assert_raise_with_message(ArgumentError, "can't omit precision for a Float.") { BigDecimal(4.2) } + assert_nothing_raised { BigDecimal(4.2) } + assert_equal(BigDecimal(4.2), BigDecimal('4.2')) assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) } assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) } @@ -242,10 +243,10 @@ def test_BigDecimal_with_exception_keyword assert_equal(nil, BigDecimal(42.quo(7), exception: false)) } assert_raise(ArgumentError) { - BigDecimal(4.2, exception: true) + BigDecimal(4.2, Float::DIG + 2, exception: true) } assert_nothing_raised(ArgumentError) { - assert_equal(nil, BigDecimal(4.2, exception: false)) + assert_equal(nil, BigDecimal(4.2, Float::DIG + 2, exception: false)) } # TODO: support conversion from complex # assert_raise(RangeError) { From 2b0946c145d21e396e5881de2736a0bdf535d71b Mon Sep 17 00:00:00 2001 From: Tim Craft Date: Mon, 9 Jun 2025 13:56:30 +0100 Subject: [PATCH 2/3] Fix typo in BigDecimal#scale comment (#348) --- ext/bigdecimal/bigdecimal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 9b86ef0b..0f2bfc13 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -664,8 +664,8 @@ BigDecimal_precision(VALUE self) * BigDecimal("1").scale # => 0 * BigDecimal("1.1").scale # => 1 * BigDecimal("3.1415").scale # => 4 - * BigDecimal("-1e20").precision # => 0 - * BigDecimal("1e-20").precision # => 20 + * BigDecimal("-1e20").scale # => 0 + * BigDecimal("1e-20").scale # => 20 * BigDecimal("Infinity").scale # => 0 * BigDecimal("-Infinity").scale # => 0 * BigDecimal("NaN").scale # => 0 From 867cac37628cd6562960204e6c7bebb03e1c2f7d Mon Sep 17 00:00:00 2001 From: Maciej Rzasa Date: Mon, 9 Jun 2025 21:17:06 +0200 Subject: [PATCH 3/3] Added tests for float --- test/bigdecimal/test_bigdecimal.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index 3db40750..74dadd75 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -168,6 +168,8 @@ def test_BigDecimal_with_float assert_equal(BigDecimal("0.01"), BigDecimal(0.01, Float::DIG + 1)) assert_nothing_raised { BigDecimal(4.2) } assert_equal(BigDecimal(4.2), BigDecimal('4.2')) + assert_equal(BigDecimal("0.12345"), BigDecimal(0.12345, 0)) + assert_equal(BigDecimal("0.12345"), BigDecimal(0.12345)) assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) } assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) }