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/