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

ruby-changes:21358

From: naruse <ko1@a...>
Date: Wed, 5 Oct 2011 16:35:38 +0900 (JST)
Subject: [ruby-changes:21358] naruse:r33407 (trunk): * numeric.c (ruby_float_step): improve floating point calculations.

naruse	2011-10-05 16:35:27 +0900 (Wed, 05 Oct 2011)

  New Revision: 33407

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

  Log:
    * numeric.c (ruby_float_step): improve floating point calculations.
      [ruby-core:35753] [Bug #4576]
    
    * numeric.c (ruby_float_step): correct the error of floating point
      numbers on the excluding case.
      patched by Masahiro Tanaka [ruby-core:39608]
    
    * numeric.c (ruby_float_step): use the end value when the current
      value is greater than or equal to the end value.
      patched by Akira Tanaka [ruby-core:39612]

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33406)
+++ ChangeLog	(revision 33407)
@@ -1,3 +1,16 @@
+Wed Sep 21 11:17:22 2011  NARUSE, Yui  <naruse@r...>
+
+	* numeric.c (ruby_float_step): improve floating point calculations.
+	  [ruby-core:35753] [Bug #4576]
+
+	* numeric.c (ruby_float_step): correct the error of floating point
+	  numbers on the excluding case.
+	  patched by Masahiro Tanaka [ruby-core:39608]
+
+	* numeric.c (ruby_float_step): use the end value when the current
+	  value is greater than or equal to the end value.
+	  patched by Akira Tanaka [ruby-core:39612]
+
 Wed Oct  5 05:56:39 2011  Eric Hodel  <drbrain@s...>
 
 	* hash.c (Init_Hash):  Improve Hash documentation.  Patch by Alvaro
Index: numeric.c
===================================================================
--- numeric.c	(revision 33406)
+++ numeric.c	(revision 33407)
@@ -1690,11 +1690,26 @@
 	}
 	else {
 	    if (err>0.5) err=0.5;
-	    n = floor(n + err);
-	    if (!excl || ((long)n)*unit+beg < end) n++;
-	    for (i=0; i<n; i++) {
-		rb_yield(DBL2NUM(i*unit+beg));
+	    if (excl) {
+		if (n>0) {
+		    if (n<err)
+			n = 1;
+		    else
+			n = floor(n - err) + 1;
+		}
+	    } else {
+		n = floor(n + err) + 1;
 	    }
+	    if (end < (n-1)*unit+beg) {
+		for (i=0; i<n; i++) {
+		    rb_yield(DBL2NUM((n-1-i)/(n-1)*beg+i/(n-1)*end));
+		}
+	    }
+	    else {
+		for (i=0; i<n; i++) {
+		    rb_yield(DBL2NUM(i*unit+beg));
+		}
+	    }
 	}
 	return TRUE;
     }
Index: test/ruby/test_float.rb
===================================================================
--- test/ruby/test_float.rb	(revision 33406)
+++ test/ruby/test_float.rb	(revision 33407)
@@ -508,4 +508,35 @@
       sleep(0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1)
     end
   end
+
+  def test_step
+    1000.times do
+      a = rand
+      b = a+rand*1000
+      s = (b - a) / 10
+      assert_equal(11, (a..b).step(s).to_a.length)
+    end
+
+    assert_equal(11, (1.0..(1.0+1E-15)).step(1E-16).to_a.length)
+
+    (1.0..12.7).step(1.3).each do |n|
+      assert_operator(n, :<=, 12.7)
+    end
+  end
+
+  def test_step_excl
+    1000.times do
+      a = rand
+      b = a+rand*1000
+      s = (b - a) / 10
+      assert_equal(10, (a...b).step(s).to_a.length)
+    end
+
+    assert_equal([1.0, 2.9, 4.8, 6.699999999999999], (1.0...6.8).step(1.9).to_a)
+
+    e = 1+1E-12
+    (1.0 ... e).step(1E-16) do |n|
+      assert_operator(n, :<, e)
+    end
+  end
 end

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

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