[前][次][番号順一覧][スレッド一覧]

ruby-changes:19119

From: nobu <ko1@a...>
Date: Wed, 23 Mar 2011 08:27:57 +0900 (JST)
Subject: [ruby-changes:19119] Ruby:r31158 (trunk): * numeric.c (flo_round): fix inaccurate results.

nobu	2011-03-23 08:07:36 +0900 (Wed, 23 Mar 2011)

  New Revision: 31158

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31158

  Log:
    * numeric.c (flo_round): fix inaccurate results.

  Modified files:
    trunk/ChangeLog
    trunk/include/ruby/intern.h
    trunk/numeric.c
    trunk/test/ruby/test_float.rb

Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 31157)
+++ include/ruby/intern.h	(revision 31158)
@@ -126,6 +126,7 @@
 VALUE rb_big_minus(VALUE, VALUE);
 VALUE rb_big_mul(VALUE, VALUE);
 VALUE rb_big_div(VALUE, VALUE);
+VALUE rb_big_idiv(VALUE, VALUE);
 VALUE rb_big_modulo(VALUE, VALUE);
 VALUE rb_big_divmod(VALUE, VALUE);
 VALUE rb_big_pow(VALUE, VALUE);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31157)
+++ ChangeLog	(revision 31158)
@@ -1,3 +1,7 @@
+Wed Mar 23 08:07:33 2011  Nobuyoshi Nakada  <nobu@r...>
+
+	* numeric.c (flo_round): fix inaccurate results.
+
 Wed Mar 23 00:12:16 2011  Tajima Akio <artonx@y...>
 
 	* win32/win32.c: wait process real termination after reading 
Index: numeric.c
===================================================================
--- numeric.c	(revision 31157)
+++ numeric.c	(revision 31158)
@@ -97,6 +97,9 @@
 }
 #endif
 
+static VALUE fix_mul(VALUE x, VALUE y);
+static VALUE int_pow(long x, unsigned long y);
+
 static ID id_coerce, id_to_i, id_eq;
 
 VALUE rb_cNumeric;
@@ -1492,7 +1495,15 @@
 	if (ndigits < 0) number = 0;
     }
     else {
-	if (ndigits < 0) number /= f;
+	if (ndigits < 0) {
+	    if (fabs(number) < f) return INT2FIX(0);
+	    if (!FIXABLE(number)) {
+		VALUE f10 = int_pow(10, -ndigits);
+		num = rb_big_idiv(rb_dbl2big(number), f10);
+		return FIXNUM_P(num) ? fix_mul(num, f10) : rb_big_mul(num, f10);
+	    }
+	    number /= f;
+	}
 	else number *= f;
 	number = round(number);
 	if (ndigits < 0) number *= f;
Index: test/ruby/test_float.rb
===================================================================
--- test/ruby/test_float.rb	(revision 31157)
+++ test/ruby/test_float.rb	(revision 31158)
@@ -320,6 +320,8 @@
     assert_equal(1.110, 1.111.round(2))
     assert_equal(11110.0, 11111.1.round(-1))
     assert_equal(11100.0, 11111.1.round(-2))
+
+    assert_equal(10**300, 1.1e300.round(-300))
   end
 
   VS = [

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]