diff --git a/ChangeLog b/ChangeLog index 6207b30a5d..9d17e7c279 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Tue May 31 22:44:00 2011 Kenta Murata + + * ext/bigdecimal/bigdecimal.c (BigDecimal_new): support instantiation a + BigDecimal object from an Integer. + + * test/bigdecimal/test_bigdecimal.rb (test_new_with_integer): + add for testing the above change. + + * ext/bigdecimal/bigdecimal.c (BigDecimal_global_new): replace its body + with a BigDecimal_new call. + + * test/bigdecimal/test_bigdecimal.rb (test_global_new_with_integer): + add for testing the above change. + Tue May 31 22:24:39 2011 Tadayoshi Funaba * ext/date/date_core.c: use simple/complex mode instead of light/right mode. diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 7f64288647..45dac45645 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -1738,37 +1738,21 @@ BigDecimal_power(VALUE self, VALUE p) return ToValue(y); } -static VALUE -BigDecimal_global_new(int argc, VALUE *argv, VALUE self) -{ - ENTER(5); - Real *pv; - size_t mf; - VALUE nFig; - VALUE iniValue; - - if(rb_scan_args(argc,argv,"11",&iniValue,&nFig)==1) { - mf = 0; - } else { - mf = GetPositiveInt(nFig); - } - SafeStringValue(iniValue); - GUARD_OBJ(pv,VpCreateRbObject(mf, RSTRING_PTR(iniValue))); - return ToValue(pv); -} - - /* call-seq: - * new(initial, digits) - * - * Create a new BigDecimal object. - * - * initial:: The initial value, as a String. Spaces are ignored, unrecognized characters terminate the value. - * - * digits:: The number of significant digits, as a Fixnum. If omitted or 0, the number of significant digits is determined from the initial value. - * - * The actual number of significant digits used in computation is usually - * larger than the specified number. - */ +/* call-seq: + * new(initial, digits) + * + * Create a new BigDecimal object. + * + * initial:: The initial value, as a String. Spaces are ignored, unrecognized + * characters terminate the value. + * + * digits:: The number of significant digits, as a Fixnum. If omitted or 0, + * the number of significant digits is determined from the initial + * value. + * + * The actual number of significant digits used in computation is usually + * larger than the specified number. + */ static VALUE BigDecimal_new(int argc, VALUE *argv, VALUE self) { @@ -1778,16 +1762,36 @@ BigDecimal_new(int argc, VALUE *argv, VALUE self) VALUE nFig; VALUE iniValue; - if(rb_scan_args(argc,argv,"11",&iniValue,&nFig)==1) { + if (rb_scan_args(argc, argv, "11", &iniValue, &nFig) == 1) { mf = 0; - } else { + } + else { mf = GetPositiveInt(nFig); } + + switch (TYPE(iniValue)) { + case T_FIXNUM: + /* fall through */ + case T_BIGNUM: + return ToValue(GetVpValue(iniValue, 1)); + + case T_STRING: + /* fall through */ + default: + break; + } SafeStringValue(iniValue); - GUARD_OBJ(pv,VpNewRbClass(mf, RSTRING_PTR(iniValue),self)); + GUARD_OBJ(pv, VpNewRbClass(mf, RSTRING_PTR(iniValue),self)); + return ToValue(pv); } +static VALUE +BigDecimal_global_new(int argc, VALUE *argv, VALUE self) +{ + return BigDecimal_new(argc, argv, rb_cBigDecimal); +} + /* call-seq: * BigDecimal.limit(digits) * diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index 810630549b..d50b0e41c3 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -29,6 +29,13 @@ class TestBigDecimal < Test::Unit::TestCase assert_raise(ArgumentError) { BigDecimal("1", -1) } end + def test_global_new_with_integer + assert_equal(BigDecimal("1"), BigDecimal(1)) + assert_equal(BigDecimal("-1"), BigDecimal(-1)) + assert_equal(BigDecimal((2**100).to_s), BigDecimal(2**100)) + assert_equal(BigDecimal((-2**100).to_s), BigDecimal(-2**100)) + end + def test_new assert_equal(1, BigDecimal.new("1")) assert_equal(1, BigDecimal.new("1", 1)) @@ -44,6 +51,13 @@ class TestBigDecimal < Test::Unit::TestCase assert_equal( 1, BigDecimal.new("1E1111111111111111111").infinite?) end + def test_new_with_integer + assert_equal(BigDecimal("1"), BigDecimal.new(1)) + assert_equal(BigDecimal("-1"), BigDecimal.new(-1)) + assert_equal(BigDecimal((2**100).to_s), BigDecimal.new(2**100)) + assert_equal(BigDecimal((-2**100).to_s), BigDecimal.new(-2**100)) + end + def _test_mode(type) BigDecimal.mode(type, true) assert_raise(FloatDomainError) { yield }