summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--bignum.c2
-rw-r--r--ext/bigdecimal/bigdecimal.c45
3 files changed, 31 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index 26ed674f46..bf27476c47 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Jan 29 01:26:53 2010 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_to_i): update RDoc to
+ denote that #to_i raises FloatDomainError for Inf and NaN.
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_to_i): fast #to_i using
+ BigDecimal_split().
+
+ * bignum.c (conv_digit): use faster ISDIGIT() assuming ASCII.
+
Fri Jan 29 00:18:54 2010 Yusuke Endoh <mame@tsg.ne.jp>
* lib/cgi.rb: set autoload to CGI::HtmlExtension. [ruby-dev:40194]
diff --git a/bignum.c b/bignum.c
index b1d3e5a685..0b464f2f1f 100644
--- a/bignum.c
+++ b/bignum.c
@@ -437,6 +437,8 @@ rb_cstr_to_inum(const char *str, int base, int badcheck)
VALUE z;
BDIGIT *zds;
+#undef ISDIGIT
+#define ISDIGIT(c) ('0' <= (c) && (c) <= '9')
#define conv_digit(c) \
(!ISASCII(c) ? -1 : \
ISDIGIT(c) ? ((c) - '0') : \
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index c6ffe98896..3dd62f11fb 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -473,9 +473,11 @@ BigDecimal_check_num(Real *p)
}
}
+static VALUE BigDecimal_split(VALUE self);
+
/* Returns the value as an integer (Fixnum or Bignum).
*
- * If the BigNumber is infinity or NaN, returns nil.
+ * If the BigNumber is infinity or NaN, raises FloatDomainError.
*/
static VALUE
BigDecimal_to_i(VALUE self)
@@ -497,31 +499,24 @@ BigDecimal_to_i(VALUE self)
e = VpGetSign(p)*p->frac[0];
return INT2FIX(e);
}
- str = rb_str_new(0, e+nf+2);
- psz = RSTRING_PTR(str);
+ else {
+ VALUE a = BigDecimal_split(self);
+ VALUE digits = RARRAY_PTR(a)[1];
+ VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0);
+ int dpower = e - RSTRING_LEN(digits);
- n = (e+nf-1)/nf;
- pch = psz;
- if(VpGetSign(p)<0) *pch++ = '-';
- for(i=0;i<n;++i) {
- b = VpBaseVal()/10;
- if(i>=(int)p->Prec) {
- while(b) {
- *pch++ = '0';
- b /= 10;
- }
- continue;
- }
- v = p->frac[i];
- while(b) {
- j = v/b;
- *pch++ = (char)(j + '0');
- v -= j*b;
- b /= 10;
- }
+ if (VpGetSign(p) < 0) {
+ numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
+ }
+ if (dpower < 0) {
+ return rb_funcall(numerator, rb_intern("div"), 1,
+ rb_funcall(INT2FIX(10), rb_intern("**"), 1,
+ INT2FIX(-dpower)));
+ }
+ return rb_funcall(numerator, '*', 1,
+ rb_funcall(INT2FIX(10), rb_intern("**"), 1,
+ INT2FIX(dpower)));
}
- *pch++ = 0;
- return rb_cstr2inum(psz,10);
}
/* Returns a new Float object having approximately the same value as the
@@ -556,8 +551,6 @@ BigDecimal_to_f(VALUE self)
}
-static VALUE BigDecimal_split(VALUE self);
-
/* Converts a BigDecimal to a Rational.
*/
static VALUE