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

ruby-changes:23126

From: naruse <ko1@a...>
Date: Fri, 30 Mar 2012 14:13:23 +0900 (JST)
Subject: [ruby-changes:23126] naruse:r35176 (ruby_1_9_3): merge revision(s) 35013:

naruse	2012-03-30 14:13:10 +0900 (Fri, 30 Mar 2012)

  New Revision: 35176

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

  Log:
    merge revision(s) 35013:
    
    * numeric.c: fix flodivmod for cornercases [Bug #6044]
      add ruby_float_mod
    
    * insns.def (opt_mod): use ruby_float_mod
    
    * internal.h: declare ruby_float_mod
    
    * test/ruby/test_float.rb: tests for above
    
    * test/ruby/envutil.rb: create helper assert_is_minus_zero

  Modified files:
    branches/ruby_1_9_3/ChangeLog
    branches/ruby_1_9_3/insns.def
    branches/ruby_1_9_3/internal.h
    branches/ruby_1_9_3/numeric.c
    branches/ruby_1_9_3/test/ruby/envutil.rb
    branches/ruby_1_9_3/test/ruby/test_float.rb
    branches/ruby_1_9_3/version.h

Index: ruby_1_9_3/ChangeLog
===================================================================
--- ruby_1_9_3/ChangeLog	(revision 35175)
+++ ruby_1_9_3/ChangeLog	(revision 35176)
@@ -1,3 +1,16 @@
+Fri Mar 30 14:12:53 2012  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* numeric.c: fix flodivmod for cornercases [Bug #6044]
+	  add ruby_float_mod
+
+	* insns.def (opt_mod): use ruby_float_mod
+
+	* internal.h: declare ruby_float_mod
+
+	* test/ruby/test_float.rb: tests for above
+
+	* test/ruby/envutil.rb: create helper assert_is_minus_zero
+
 Wed Mar 28 08:44:24 2012  Aaron Patterson <aaron@t...>
 
 	* ext/psych/lib/psych.rb: updating version to match gem
Index: ruby_1_9_3/insns.def
===================================================================
--- ruby_1_9_3/insns.def	(revision 35175)
+++ ruby_1_9_3/insns.def	(revision 35176)
@@ -1611,23 +1611,7 @@
 	else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
 		 HEAP_CLASS_OF(obj) == rb_cFloat &&
 		 BASIC_OP_UNREDEFINED_P(BOP_MOD)) {
-	    double x = RFLOAT_VALUE(recv);
-	    double y = RFLOAT_VALUE(obj);
-	    double div, mod;
-
-	    {
-		double z;
-
-		modf(x / y, &z);
-		mod = x - z * y;
-	    }
-
-	    div = (x - mod) / y;
-	    if (y * mod < 0) {
-		mod += y;
-		div -= 1.0;
-	    }
-	    val = DBL2NUM(mod);
+	    val = DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
 	}
 	else {
 	    goto INSN_LABEL(normal_dispatch);
Index: ruby_1_9_3/numeric.c
===================================================================
--- ruby_1_9_3/numeric.c	(revision 35175)
+++ ruby_1_9_3/numeric.c	(revision 35176)
@@ -817,7 +817,9 @@
 #ifdef HAVE_FMOD
     mod = fmod(x, y);
 #else
-    {
+    if((x == 0.0) || (isinf(y) && !isinf(x)))
+        mod = x;
+    else {
 	double z;
 
 	modf(x/y, &z);
@@ -836,7 +838,18 @@
     if (divp) *divp = div;
 }
 
+/*
+ * Returns the modulo of division of x by y.
+ * An error will be raised if y == 0.
+ */
 
+double ruby_float_mod(double x, double y) {
+    double mod;
+    flodivmod(x, y, 0, &mod);
+    return mod;
+}
+
+
 /*
  *  call-seq:
  *     flt % other        ->  float
@@ -851,7 +864,7 @@
 static VALUE
 flo_mod(VALUE x, VALUE y)
 {
-    double fy, mod;
+    double fy;
 
     switch (TYPE(y)) {
       case T_FIXNUM:
@@ -866,8 +879,7 @@
       default:
 	return rb_num_coerce_bin(x, y, '%');
     }
-    flodivmod(RFLOAT_VALUE(x), fy, 0, &mod);
-    return DBL2NUM(mod);
+    return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(x), fy));
 }
 
 static VALUE
@@ -2648,12 +2660,7 @@
 	x = rb_int2big(FIX2LONG(x));
 	return rb_big_modulo(x, y);
       case T_FLOAT:
-	{
-	    double mod;
-
-	    flodivmod((double)FIX2LONG(x), RFLOAT_VALUE(y), 0, &mod);
-	    return DBL2NUM(mod);
-	}
+	return DBL2NUM(ruby_float_mod((double)FIX2LONG(x), RFLOAT_VALUE(y)));
       default:
 	return rb_num_coerce_bin(x, y, '%');
     }
Index: ruby_1_9_3/internal.h
===================================================================
--- ruby_1_9_3/internal.h	(revision 35175)
+++ ruby_1_9_3/internal.h	(revision 35176)
@@ -130,6 +130,7 @@
 /* numeric.c */
 int rb_num_to_uint(VALUE val, unsigned int *ret);
 int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl);
+double ruby_float_mod(double x, double y);
 
 /* object.c */
 VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
Index: ruby_1_9_3/version.h
===================================================================
--- ruby_1_9_3/version.h	(revision 35175)
+++ ruby_1_9_3/version.h	(revision 35176)
@@ -1,10 +1,10 @@
 #define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 168
+#define RUBY_PATCHLEVEL 169
 
-#define RUBY_RELEASE_DATE "2012-03-29"
+#define RUBY_RELEASE_DATE "2012-03-30"
 #define RUBY_RELEASE_YEAR 2012
 #define RUBY_RELEASE_MONTH 3
-#define RUBY_RELEASE_DAY 29
+#define RUBY_RELEASE_DAY 30
 
 #include "ruby/version.h"
 
Index: ruby_1_9_3/test/ruby/test_float.rb
===================================================================
--- ruby_1_9_3/test/ruby/test_float.rb	(revision 35175)
+++ ruby_1_9_3/test/ruby/test_float.rb	(revision 35176)
@@ -195,6 +195,18 @@
     assert_raise(TypeError) { 2.0.send(:%, nil) }
   end
 
+  def test_modulo3
+    bug6048 = '[ruby-core:42726]'
+    assert_equal(4.2, 4.2.send(:%, Float::INFINITY))
+    assert_equal(4.2, 4.2 % Float::INFINITY)
+    assert_is_minus_zero(-0.0 % 4.2)
+    assert_is_minus_zero(-0.0.send :%, 4.2)
+    assert_raise(ZeroDivisionError) { 4.2.send(:%, 0.0) }
+    assert_raise(ZeroDivisionError) { 4.2 % 0.0 }
+    assert_raise(ZeroDivisionError) { 42.send(:%, 0) }
+    assert_raise(ZeroDivisionError) { 42 % 0 }
+  end
+
   def test_divmod2
     assert_equal([1.0, 0.0], 2.0.divmod(2))
     assert_equal([1.0, 0.0], 2.0.divmod((2**32).coerce(2).first))
Index: ruby_1_9_3/test/ruby/envutil.rb
===================================================================
--- ruby_1_9_3/test/ruby/envutil.rb	(revision 35175)
+++ ruby_1_9_3/test/ruby/envutil.rb	(revision 35176)
@@ -184,6 +184,10 @@
         assert(msg === stderr, "warning message #{stderr.inspect} is expected to match #{msg.inspect}")
       end
 
+
+      def assert_is_minus_zero(f)
+        assert(1.0/f == -Float::INFINITY, "#{f} is not -0.0")
+      end
     end
   end
 end

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

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