diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | ext/bigdecimal/bigdecimal.c | 96 | ||||
-rw-r--r-- | test/bigdecimal/test_bigdecimal.rb | 7 |
3 files changed, 93 insertions, 21 deletions
@@ -1,3 +1,14 @@ +Mon Jun 13 18:49:00 2011 Kenta Murata <mrkn@mrkn.jp> + + * ext/bigdecimal/bigdecimal.c (BigDecimalCmp): use GetVpValueWithPrec + for Float and Rational arguments. + + * test/bigdecimal/test_bigdecimal.rb (test_new, test_cmp, test_power): + add and modify tests for the above change. + + * ext/bigdecimal/bigdecimal.c (BigDecimalCmp): modify coding style to + match ruby's standard. + Mon Jun 13 18:33:04 2011 Tanaka Akira <akr@fsij.org> * lib/securerandom.rb (SecureRandom.random_bytes): modify PRNG state diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 388dbbdcf8..c21dd8c5ce 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -794,34 +794,90 @@ BigDecimalCmp(VALUE self, VALUE r,char op) { ENTER(5); SIGNED_VALUE e; - Real *a, *b; + Real *a, *b=0; GUARD_OBJ(a,GetVpValue(self,1)); - b = GetVpValue(r,0); - if(!b) { + switch (TYPE(r)) { + case T_DATA: + if (!rb_typeddata_is_kind_of(r, &BigDecimal_data_type)) break; + /* fall through */ + case T_FIXNUM: + /* fall through */ + case T_BIGNUM: + GUARD_OBJ(b, GetVpValue(r,0)); + break; + + case T_FLOAT: + GUARD_OBJ(b, GetVpValueWithPrec(r, DBL_DIG+1, 0)); + break; + + case T_RATIONAL: + GUARD_OBJ(b, GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 0)); + break; + + default: + break; + } + if (b == NULL) { ID f = 0; - switch(op) - { - case '*': return rb_num_coerce_cmp(self,r,rb_intern("<=>")); - case '=': return RTEST(rb_num_coerce_cmp(self,r,rb_intern("=="))) ? Qtrue : Qfalse; - case 'G': f = rb_intern(">="); break; - case 'L': f = rb_intern("<="); break; - case '>': case '<': f = (ID)op; break; + switch (op) { + case '*': + return rb_num_coerce_cmp(self, r, rb_intern("<=>")); + + case '=': + return RTEST(rb_num_coerce_cmp(self, r, rb_intern("=="))) ? Qtrue : Qfalse; + + case 'G': + f = rb_intern(">="); + break; + + case 'L': + f = rb_intern("<="); + break; + + case '>': + /* fall through */ + case '<': + f = (ID)op; + break; + + default: + break; } - return rb_num_coerce_relop(self,r,f); + return rb_num_coerce_relop(self, r, f); } SAVE(b); e = VpComp(a, b); - if(e==999) return (op == '*') ? Qnil : Qfalse; - switch(op) - { - case '*': return INT2FIX(e); /* any op */ - case '=': if(e==0) return Qtrue ; return Qfalse; - case 'G': if(e>=0) return Qtrue ; return Qfalse; - case '>': if(e> 0) return Qtrue ; return Qfalse; - case 'L': if(e<=0) return Qtrue ; return Qfalse; - case '<': if(e< 0) return Qtrue ; return Qfalse; + if (e == 999) + return (op == '*') ? Qnil : Qfalse; + switch (op) { + case '*': + return INT2FIX(e); /* any op */ + + case '=': + if(e==0) return Qtrue; + return Qfalse; + + case 'G': + if(e>=0) return Qtrue; + return Qfalse; + + case '>': + if(e> 0) return Qtrue; + return Qfalse; + + case 'L': + if(e<=0) return Qtrue; + return Qfalse; + + case '<': + if(e< 0) return Qtrue; + return Qfalse; + + default: + break; } + rb_bug("Undefined operation in BigDecimalCmp()"); } diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index c0c5ea44a0..30044f1b6c 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -56,6 +56,7 @@ class TestBigDecimal < Test::Unit::TestCase assert_equal(1, BigDecimal.new(" 1 ")) assert_equal(111, BigDecimal.new("1_1_1_")) assert_equal(0, BigDecimal.new("_1_1_1")) + assert_equal(10**(-1), BigDecimal.new("1E-1"), '#4825') BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) @@ -351,6 +352,9 @@ class TestBigDecimal < Test::Unit::TestCase inf = BigDecimal.new("Infinity") assert_operator(inf, :>, 1) assert_operator(1, :<, inf) + + assert_operator(BigDecimal("1E-1"), :==, 10**(-1), '#4825') + assert_equal(0, BigDecimal("1E-1") <=> 10**(-1), '#4825') end def test_cmp_nan @@ -763,7 +767,8 @@ class TestBigDecimal < Test::Unit::TestCase def test_power x = BigDecimal.new("3") assert_equal(81, x ** 4) - assert_equal(1.0/81, x ** -4) + assert_equal(1.0/81, (x ** -4).to_f) + assert_equal(1.quo(81), x ** -4) assert_equal(1, x ** 0) assert_raise(TypeError) { x ** x } assert_equal(0, BigDecimal.new("0") ** 4) |