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

ruby-changes:21109

From: nobu <ko1@a...>
Date: Fri, 2 Sep 2011 01:07:28 +0900 (JST)
Subject: [ruby-changes:21109] nobu:r33158 (trunk): * numeric.c (flo_round): substitute machine dependent magic number.

nobu	2011-09-02 01:07:16 +0900 (Fri, 02 Sep 2011)

  New Revision: 33158

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

  Log:
    * numeric.c (flo_round): substitute machine dependent magic number.

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33157)
+++ ChangeLog	(revision 33158)
@@ -1,3 +1,7 @@
+Fri Sep  2 01:07:14 2011  Nobuyoshi Nakada  <nobu@r...>
+
+	* numeric.c (flo_round): substitute machine dependent magic number.
+
 Thu Sep  1 17:31:22 2011  Nobuyoshi Nakada  <nobu@r...>
 
 	* insns.def (defineclass), vm_insnhelper.c (vm_get_cvar_base): see
Index: numeric.c
===================================================================
--- numeric.c	(revision 33157)
+++ numeric.c	(revision 33158)
@@ -1493,17 +1493,18 @@
     int ndigits = 0;
     int binexp;
     long val;
+    enum {float_dig = DBL_DIG+2};
 
     if (argc > 0 && rb_scan_args(argc, argv, "01", &nd) == 1) {
 	ndigits = NUM2INT(nd);
     }
     number  = RFLOAT_VALUE(num);
-    frexp (number , &binexp);
+    frexp(number, &binexp);
 
 /* Let `exp` be such that `number` is written as:"0.#{digits}e#{exp}",
    i.e. such that  10 ** (exp - 1) <= |number| < 10 ** exp
-   Recall that up to 17 digits can be needed to represent a double,
-   so if ndigits + exp >= 17, the intermediate value (number * 10 ** ndigits)
+   Recall that up to float_dig digits can be needed to represent a double,
+   so if ndigits + exp >= float_dig, the intermediate value (number * 10 ** ndigits)
    will be an integer and thus the result is the original number.
    If ndigits + exp <= 0, the result is 0 or "1e#{exp}", so
    if ndigits + exp < 0, the result is 0.
@@ -1514,7 +1515,7 @@
 	   10 ** (binexp/4 - 1) < |number| < 10 ** (binexp/3)
 	   binexp/4 <= exp <= binexp/3
 	If binexp <= 0, swap the /4 and the /3
-	So if ndigits + binexp/(4 or 3) >= 17, the result is number
+	So if ndigits + binexp/(4 or 3) >= float_dig, the result is number
 	If ndigits + binexp/(3 or 4) < 0 the result is 0
 */
     if (isinf(number) || isnan(number)) {
@@ -1523,7 +1524,7 @@
     else if ((long)ndigits * (4 - (binexp > 0)) + binexp < 0) {
 	number = 0;
     }
-    else if (((long)ndigits - 17) * (3 + (binexp > 0)) + binexp < 0) {
+    else if (((long)ndigits - float_dig) * (3 + (binexp > 0)) + binexp < 0) {
 	f = pow(10, abs(ndigits));
 	if (ndigits < 0) {
 	    double absnum = fabs(number);
Index: test/ruby/test_float.rb
===================================================================
--- test/ruby/test_float.rb	(revision 33157)
+++ test/ruby/test_float.rb	(revision 33158)
@@ -315,7 +315,9 @@
     assert_raise(FloatDomainError) { inf.ceil }
     assert_raise(FloatDomainError) { inf.round }
     assert_raise(FloatDomainError) { inf.truncate }
+  end
 
+  def test_round_with_precision
     assert_equal(1.100, 1.111.round(1))
     assert_equal(1.110, 1.111.round(2))
     assert_equal(11110.0, 11111.1.round(-1))
@@ -323,6 +325,17 @@
 
     assert_equal(10**300, 1.1e300.round(-300))
     assert_equal(-10**300, -1.1e300.round(-300))
+    assert_equal(1.0e-300, 1.1e-300.round(300))
+    assert_equal(-1.0e-300, -1.1e-300.round(300))
+
+    bug5227 = '[ruby-core:39093]'
+    assert_equal(42.0, 42.0.round(308), bug5227)
+    assert_equal(1.0e307, 1.0e307.round(2), bug5227)
+
+    assert_raise(TypeError) {1.0.round("4")}
+    assert_raise(TypeError) {1.0.round(nil)}
+    def (prec = Object.new).to_int; 2; end
+    assert_equal(1.0, 0.998.round(prec))
   end
 
   VS = [

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

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