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

ruby-changes:37918

From: nobu <ko1@a...>
Date: Wed, 18 Mar 2015 12:02:30 +0900 (JST)
Subject: [ruby-changes:37918] nobu:r49999 (trunk): hash.c: same hash values with Float#hash

nobu	2015-03-18 12:01:58 +0900 (Wed, 18 Mar 2015)

  New Revision: 49999

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

  Log:
    hash.c: same hash values with Float#hash
    
    * hash.c (rb_any_hash): use same hash values with Float#hash so
      that -0.0 and +0.0 will be identical.
      [ruby-core:68541] [Bug #10979]

  Modified files:
    trunk/ChangeLog
    trunk/hash.c
    trunk/internal.h
    trunk/numeric.c
    trunk/test/ruby/test_float.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 49998)
+++ ChangeLog	(revision 49999)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Mar 18 12:01:53 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* hash.c (rb_any_hash): use same hash values with Float#hash so
+	  that -0.0 and +0.0 will be identical.
+	  [ruby-core:68541] [Bug #10979]
+
 Wed Mar 18 05:34:32 2015  Koichi Sasada  <ko1@a...>
 
 	* string.c: introduce STR_FAKESTR to show string is FAKESTR or not.
Index: hash.c
===================================================================
--- hash.c	(revision 49998)
+++ hash.c	(revision 49999)
@@ -142,13 +142,16 @@ rb_any_hash(VALUE a) https://github.com/ruby/ruby/blob/trunk/hash.c#L142
 	}
 	else if (FLONUM_P(a)) {
 	    /* prevent pathological behavior: [Bug #10761] */
-	    a = (st_index_t)rb_float_value(a);
+	    return rb_dbl_hash(rb_float_value(a));
 	}
 	hnum = rb_objid_hash((st_index_t)a);
     }
     else if (BUILTIN_TYPE(a) == T_STRING) {
 	hnum = rb_str_hash(a);
     }
+    else if (BUILTIN_TYPE(a) == T_FLOAT) {
+	return rb_dbl_hash(rb_float_value(a));
+    }
     else {
         hval = rb_hash(a);
 	hnum = FIX2LONG(hval);
Index: numeric.c
===================================================================
--- numeric.c	(revision 49998)
+++ numeric.c	(revision 49999)
@@ -1137,10 +1137,14 @@ flo_eq(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L1137
 static VALUE
 flo_hash(VALUE num)
 {
-    double d;
+    return rb_dbl_hash(RFLOAT_VALUE(num));
+}
+
+VALUE
+rb_dbl_hash(double d)
+{
     st_index_t hash;
 
-    d = RFLOAT_VALUE(num);
     /* normalize -0.0 to 0.0 */
     if (d == 0.0) d = 0.0;
     hash = rb_memhash(&d, sizeof(d));
Index: internal.h
===================================================================
--- internal.h	(revision 49998)
+++ internal.h	(revision 49999)
@@ -885,6 +885,7 @@ double ruby_float_mod(double x, double y https://github.com/ruby/ruby/blob/trunk/internal.h#L885
 int rb_num_negative_p(VALUE);
 VALUE rb_int_succ(VALUE num);
 VALUE rb_int_pred(VALUE num);
+VALUE rb_dbl_hash(double d);
 
 #if USE_FLONUM
 #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
Index: test/ruby/test_float.rb
===================================================================
--- test/ruby/test_float.rb	(revision 49998)
+++ test/ruby/test_float.rb	(revision 49999)
@@ -672,4 +672,12 @@ class TestFloat < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_float.rb#L672
     assert_equal(0.0, z)
     assert_equal(-Float::INFINITY, 1.0/z)
   end
+
+  def test_hash_0
+    bug10979 = '[ruby-core:68541] [Bug #10979]' 
+    assert_equal(+0.0.hash, -0.0.hash)
+    assert_operator(+0.0, :eql?, -0.0)
+    h = {0.0 => bug10979}
+    assert_equal(bug10979, h[-0.0])
+  end
 end

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

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