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

ruby-changes:27012

From: marcandre <ko1@a...>
Date: Tue, 5 Feb 2013 14:39:59 +0900 (JST)
Subject: [ruby-changes:27012] marcandRe: r39064 (trunk): * numeric.c (fix_pow): Handle special cases when base is 0, -1 or +1

marcandre	2013-02-05 14:39:49 +0900 (Tue, 05 Feb 2013)

  New Revision: 39064

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

  Log:
    * numeric.c (fix_pow): Handle special cases when base is 0, -1 or +1
      [Bug #5713] [Bug #5715]

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 39063)
+++ ChangeLog	(revision 39064)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Feb  5 14:36:04 2013  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* numeric.c (fix_pow): Handle special cases when base is 0, -1 or +1
+	  [Bug #5713] [Bug #5715]
+
+	* rational.c (nurat_expt): ditto
+
 Tue Feb  5 13:27:53 2013  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/io/console/console.c (rawmode_opt): use default values by `stty
Index: numeric.c
===================================================================
--- numeric.c	(revision 39063)
+++ numeric.c	(revision 39064)
@@ -2951,6 +2951,13 @@ fix_pow(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L2951
     if (FIXNUM_P(y)) {
 	long b = FIX2LONG(y);
 
+	if (a == 1) return INT2FIX(1);
+	if (a == -1) {
+	    if (b % 2 == 0)
+		return INT2FIX(1);
+	    else
+		return INT2FIX(-1);
+	}
 	if (b < 0)
 	    return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
 
@@ -2960,27 +2967,18 @@ fix_pow(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L2967
 	    if (b > 0) return INT2FIX(0);
 	    return DBL2NUM(INFINITY);
 	}
-	if (a == 1) return INT2FIX(1);
-	if (a == -1) {
-	    if (b % 2 == 0)
-		return INT2FIX(1);
-	    else
-		return INT2FIX(-1);
-	}
 	return int_pow(a, b);
     }
     switch (TYPE(y)) {
       case T_BIGNUM:
-
-	if (negative_int_p(y))
-	    return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
-
-	if (a == 0) return INT2FIX(0);
 	if (a == 1) return INT2FIX(1);
 	if (a == -1) {
 	    if (int_even_p(y)) return INT2FIX(1);
 	    else return INT2FIX(-1);
 	}
+	if (negative_int_p(y))
+	    return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
+	if (a == 0) return INT2FIX(0);
 	x = rb_int2big(FIX2LONG(x));
 	return rb_big_pow(x, y);
       case T_FLOAT:
Index: test/ruby/test_fixnum.rb
===================================================================
--- test/ruby/test_fixnum.rb	(revision 39063)
+++ test/ruby/test_fixnum.rb	(revision 39064)
@@ -279,4 +279,23 @@ class TestFixnum < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_fixnum.rb#L279
   def test_frozen
     assert_equal(true, 1.frozen?)
   end
+
+  def assert_eql(a, b, mess)
+    assert a.eql?(b), "expected #{a} & #{b} to be eql? #{mess}"
+  end
+
+  def test_power_of_1_and_minus_1
+    bug5715 = '[ruby-core:41498]'
+    big = 1 << 66
+    assert_eql  1, 1 ** -big        , bug5715
+    assert_eql  1, (-1) ** -big     , bug5715
+    assert_eql -1, (-1) ** -(big+1) , bug5715
+  end
+
+  def test_power_of_0
+    bug5713 = '[ruby-core:41494]'
+    big = 1 << 66
+    assert_raise(ZeroDivisionError, bug5713) { 0 ** -big }
+    assert_raise(ZeroDivisionError, bug5713) { 0 ** Rational(-2,3) }
+  end
 end

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

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