diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 70e1bf7e..47b10d6a 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -481,6 +481,24 @@ BigDecimal_scale(VALUE self) return SSIZET2NUM(scale); } +/* + * call-seq: + * precision_scale -> [integer, integer] + * + * Returns a 2-length array; the first item is the result of + * BigDecimal#precision and the second one is of BigDecimal#scale. + * + * See BigDecimal#precision. + * See BigDecimal#scale. + */ +static VALUE +BigDecimal_precision_scale(VALUE self) +{ + ssize_t precision, scale; + BigDecimal_count_precision_and_scale(self, &precision, &scale); + return rb_assoc_new(SSIZET2NUM(precision), SSIZET2NUM(scale)); +} + /* * call-seq: * n_significant_digits -> integer @@ -4228,6 +4246,7 @@ Init_bigdecimal(void) rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0); rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0); rb_define_method(rb_cBigDecimal, "scale", BigDecimal_scale, 0); + rb_define_method(rb_cBigDecimal, "precision_scale", BigDecimal_precision_scale, 0); rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0); rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2); diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index f2162caf..273abf78 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -2123,6 +2123,17 @@ def test_scale_special end end + def test_precision_scale + assert_equal([2, 0], BigDecimal("11.0").precision_scale) + assert_equal([2, 1], BigDecimal("1.1").precision_scale) + assert_equal([2, 2], BigDecimal("0.11").precision_scale) + + BigDecimal.save_exception_mode do + BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) + assert_equal([0, 0], BigDecimal("Infinity").precision_scale) + end + end + def test_n_significant_digits_only_integer assert_equal(0, BigDecimal(0).n_significant_digits) assert_equal(1, BigDecimal(1).n_significant_digits)