From e644398bc6a06490e504f6ce18963431f18641ad Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 11 Nov 2008 10:45:21 +0000 Subject: * ext/bigdecimal/bigdecimal.c (BigDecimal_to_r): moved from bigdecimal/util, converted into C. [ruby-dev:36805] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20191 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/bigdecimal/bigdecimal.c | 36 +++++++++++++++++++++++++++++++++++ ext/bigdecimal/lib/bigdecimal/util.rb | 12 ------------ 2 files changed, 36 insertions(+), 12 deletions(-) (limited to 'ext') diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index fbc2474edf..96bd88160c 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -606,6 +606,41 @@ BigDecimal_to_f(VALUE self) return rb_float_new(d); } + +static VALUE BigDecimal_split(VALUE self); + +/* Converts a BigDecimal to a Rational. + */ +static VALUE +BigDecimal_to_r(VALUE self) +{ + Real *p; + S_LONG sign, power, denomi_power; + VALUE a, digits, numerator; + + p = GetVpValue(self,1); + sign = VpGetSign(p); + power = VpExponent10(p); + a = BigDecimal_split(self); + digits = RARRAY_PTR(a)[1]; + denomi_power = power - RSTRING_LEN(digits); + numerator = rb_funcall(digits, rb_intern("to_i"), 0); + + if (sign < 0) { + numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); + } + if (denomi_power < 0) { + return rb_Rational(numerator, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(-denomi_power))); + } + else { + return rb_Rational1(rb_funcall(numerator, '*', 1, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(denomi_power)))); + } +} + /* The coerce method provides support for Ruby type coercion. It is not * enabled by default. * @@ -1918,6 +1953,7 @@ Init_bigdecimal(void) rb_define_method(rb_cBigDecimal, "to_s", BigDecimal_to_s, -1); rb_define_method(rb_cBigDecimal, "to_i", BigDecimal_to_i, 0); rb_define_method(rb_cBigDecimal, "to_int", BigDecimal_to_i, 0); + rb_define_method(rb_cBigDecimal, "to_r", BigDecimal_to_r, 0); rb_define_method(rb_cBigDecimal, "split", BigDecimal_split, 0); rb_define_method(rb_cBigDecimal, "+", BigDecimal_add, 1); rb_define_method(rb_cBigDecimal, "-", BigDecimal_sub, 1); diff --git a/ext/bigdecimal/lib/bigdecimal/util.rb b/ext/bigdecimal/lib/bigdecimal/util.rb index 09e926acd5..257781f035 100644 --- a/ext/bigdecimal/lib/bigdecimal/util.rb +++ b/ext/bigdecimal/lib/bigdecimal/util.rb @@ -39,18 +39,6 @@ class BigDecimal < Numeric i + "." + ("0"*(-z)) + f end end - - # Converts a BigDecimal to a Rational. - def to_r - sign,digits,base,power = self.split - numerator = sign*digits.to_i - denomi_power = power - digits.size # base is always 10 - if denomi_power < 0 - Rational(numerator,base ** (-denomi_power)) - else - Rational(numerator * (base ** denomi_power),1) - end - end end class Rational < Numeric -- cgit v1.2.3