diff options
Diffstat (limited to 'spec/ruby/core/integer/shared/exponent.rb')
| -rw-r--r-- | spec/ruby/core/integer/shared/exponent.rb | 136 |
1 files changed, 90 insertions, 46 deletions
diff --git a/spec/ruby/core/integer/shared/exponent.rb b/spec/ruby/core/integer/shared/exponent.rb index f292cc2448..0be13859f9 100644 --- a/spec/ruby/core/integer/shared/exponent.rb +++ b/spec/ruby/core/integer/shared/exponent.rb @@ -1,58 +1,78 @@ describe :integer_exponent, shared: true do context "fixnum" do it "returns self raised to the given power" do - 2.send(@method, 0).should eql 1 - 2.send(@method, 1).should eql 2 - 2.send(@method, 2).should eql 4 + 2.send(@method, 0).should.eql? 1 + 2.send(@method, 1).should.eql? 2 + 2.send(@method, 2).should.eql? 4 - 9.send(@method, 0.5).should eql 3.0 - 9.send(@method, Rational(1, 2)).should eql 3.0 + 9.send(@method, 0.5).should.eql? 3.0 + 9.send(@method, Rational(1, 2)).should.eql? 3.0 5.send(@method, -1).to_f.to_s.should == '0.2' - 2.send(@method, 40).should eql 1099511627776 + 2.send(@method, 40).should.eql? 1099511627776 end it "overflows the answer to a bignum transparently" do - 2.send(@method, 29).should eql 536870912 - 2.send(@method, 30).should eql 1073741824 - 2.send(@method, 31).should eql 2147483648 - 2.send(@method, 32).should eql 4294967296 + 2.send(@method, 29).should.eql? 536870912 + 2.send(@method, 30).should.eql? 1073741824 + 2.send(@method, 31).should.eql? 2147483648 + 2.send(@method, 32).should.eql? 4294967296 - 2.send(@method, 61).should eql 2305843009213693952 - 2.send(@method, 62).should eql 4611686018427387904 - 2.send(@method, 63).should eql 9223372036854775808 - 2.send(@method, 64).should eql 18446744073709551616 - 8.send(@method, 23).should eql 590295810358705651712 + 2.send(@method, 61).should.eql? 2305843009213693952 + 2.send(@method, 62).should.eql? 4611686018427387904 + 2.send(@method, 63).should.eql? 9223372036854775808 + 2.send(@method, 64).should.eql? 18446744073709551616 + 8.send(@method, 23).should.eql? 590295810358705651712 end it "raises negative numbers to the given power" do - (-2).send(@method, 29).should eql(-536870912) - (-2).send(@method, 30).should eql(1073741824) - (-2).send(@method, 31).should eql(-2147483648) - (-2).send(@method, 32).should eql(4294967296) + (-2).send(@method, 29).should.eql?(-536870912) + (-2).send(@method, 30).should.eql?(1073741824) + (-2).send(@method, 31).should.eql?(-2147483648) + (-2).send(@method, 32).should.eql?(4294967296) + (-2).send(@method, 33).should.eql?(-8589934592) - (-2).send(@method, 61).should eql(-2305843009213693952) - (-2).send(@method, 62).should eql(4611686018427387904) - (-2).send(@method, 63).should eql(-9223372036854775808) - (-2).send(@method, 64).should eql(18446744073709551616) + (-2).send(@method, 61).should.eql?(-2305843009213693952) + (-2).send(@method, 62).should.eql?(4611686018427387904) + (-2).send(@method, 63).should.eql?(-9223372036854775808) + (-2).send(@method, 64).should.eql?(18446744073709551616) + (-2).send(@method, 65).should.eql?(-36893488147419103232) end it "can raise 1 to a bignum safely" do - 1.send(@method, 4611686018427387904).should eql 1 + 1.send(@method, 4611686018427387904).should.eql? 1 end it "can raise -1 to a bignum safely" do - (-1).send(@method, 4611686018427387904).should eql(1) - (-1).send(@method, 4611686018427387905).should eql(-1) + (-1).send(@method, 4611686018427387904).should.eql?(1) + (-1).send(@method, 4611686018427387905).should.eql?(-1) end - it "returns Float::INFINITY when the number is too big" do - 2.send(@method, 427387904).should == Float::INFINITY + ruby_version_is ""..."3.4" do + it "returns Float::INFINITY when the number is too big" do + -> { + 2.send(@method, 427387904).should == Float::INFINITY + }.should complain(/warning: in a\*\*b, b may be too big/) + end + end + + ruby_version_is "3.4" do + it "returns an Integer for results larger than the old 32MB limit" do + # 2 ** 40000000 requires 40000001 bits + # This exceeds the old 32MB limit but is within the new 16GB limit + result = 2.send(@method, 40000000) + result.should.is_a?(Integer) + result.bit_length.should == 40000001 + end + + it "raises an ArgumentError when the result size exceeds the limit" do + -> { 100000000.send(@method, 1000000000) }.should.raise(ArgumentError) + end end it "raises a ZeroDivisionError for 0 ** -1" do - -> { 0.send(@method, -1) }.should raise_error(ZeroDivisionError) - -> { 0.send(@method, Rational(-1, 1)) }.should raise_error(ZeroDivisionError) + -> { 0.send(@method, -1) }.should.raise(ZeroDivisionError) + -> { 0.send(@method, Rational(-1, 1)) }.should.raise(ZeroDivisionError) end it "returns Float::INFINITY for 0 ** -1.0" do @@ -60,9 +80,9 @@ describe :integer_exponent, shared: true do end it "raises a TypeError when given a non-numeric power" do - -> { 13.send(@method, "10") }.should raise_error(TypeError) - -> { 13.send(@method, :symbol) }.should raise_error(TypeError) - -> { 13.send(@method, nil) }.should raise_error(TypeError) + -> { 13.send(@method, "10") }.should.raise(TypeError) + -> { 13.send(@method, :symbol) }.should.raise(TypeError) + -> { 13.send(@method, nil) }.should.raise(TypeError) end it "coerces power and calls #**" do @@ -94,25 +114,49 @@ describe :integer_exponent, shared: true do end it "returns self raised to other power" do - (@bignum.send(@method, 4)).should == 7237005577332262361485077344629993318496048279512298547155833600056910050625 - (@bignum.send(@method, 1.2)).should be_close(57262152889751597425762.57804, TOLERANCE) + (@bignum.send(@method, 4)).should == 115792089237316196603666111261383895964500887398800252671052694326794607293761 + (@bignum.send(@method, 1.3)).should be_close(11109528802438156839288832.0, TOLERANCE) end it "raises a TypeError when given a non-Integer" do - -> { @bignum.send(@method, mock('10')) }.should raise_error(TypeError) - -> { @bignum.send(@method, "10") }.should raise_error(TypeError) - -> { @bignum.send(@method, :symbol) }.should raise_error(TypeError) - end - - it "switch to a Float when the values is too big" do - flt = @bignum.send(@method, @bignum) - flt.should be_kind_of(Float) - flt.infinite?.should == 1 + -> { @bignum.send(@method, mock('10')) }.should.raise(TypeError) + -> { @bignum.send(@method, "10") }.should.raise(TypeError) + -> { @bignum.send(@method, :symbol) }.should.raise(TypeError) + end + + ruby_version_is ""..."3.4" do + it "switch to a Float when the values is too big" do + flt = nil + -> { + flt = @bignum.send(@method, @bignum) + }.should complain(/warning: in a\*\*b, b may be too big/) + flt.should.is_a?(Float) + flt.infinite?.should == 1 + end + end + + ruby_version_is "3.4" do + it "returns an Integer for large Bignum results exceeding the old limit" do + # (2 ** 70) ** 500000 requires 35000001 bits + # This exceeds the old 32MB limit but is within the new 16GB limit + bignum_base = 2 ** 70 + result = bignum_base.send(@method, 500000) + result.should.is_a?(Integer) + result.bit_length.should == 35000001 + end + + it "raises an ArgumentError when Bignum result exceeds the limit" do + # @bignum ** @bignum would require enormous memory + -> { + @bignum.send(@method, @bignum) + }.should.raise(ArgumentError) + end end it "returns a complex number when negative and raised to a fractional power" do - ((-@bignum).send(@method, (1.0/3))) .should be_close(Complex(1048576,1816186.907597341), TOLERANCE) - ((-@bignum).send(@method, Rational(1,3))).should be_close(Complex(1048576,1816186.907597341), TOLERANCE) + (-bignum_value).send(@method, (1.0/2)).should be_close(Complex(0.0, 4294967296.0), TOLERANCE) + (-@bignum).send(@method, (1.0/3)) .should be_close(Complex(1321122.9748145656, 2288252.1154253655), TOLERANCE) + (-@bignum).send(@method, Rational(1,3)).should be_close(Complex(1321122.9748145656, 2288252.1154253655), TOLERANCE) end end end |
