Skip to content

[Ruby 2.5] Integer#pow accepts modulo argument for calculating modular exponentiation - #573

Merged
andrykonchin merged 6 commits into
ruby:masterfrom
andrykonchin:integer-pow-accepts-modulo-argument
Jan 2, 2018
Merged

[Ruby 2.5] Integer#pow accepts modulo argument for calculating modular exponentiation#573
andrykonchin merged 6 commits into
ruby:masterfrom
andrykonchin:integer-pow-accepts-modulo-argument

Conversation

@andrykonchin

@andrykonchinandrykonchin commented Dec 27, 2017

Copy link
Copy Markdown
Member

Comment threadcore/integer/pow_spec.rb Outdated
2.pow(40).should eql 1099511627776
end

it "overflows the answer to a bignum transparantly" do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transparently


context "second argument is passed" do
it "returns modulo of self raised to the given power" do
2.pow(5, 12).should == 8

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to have a few extra examples here, notably with Bignum-range values and other numeric types.

2.pow(62, 5843009213693952).should eql 1
2.pow(63, 5843009213693953).should eql 1
2.pow(64, 5843009213693954).should eql 1
end

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like a bug:
2.pow(61, 9213693951) # => 1
but
(2 ** 61) % 9213693951 # => 5432161352

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed, could you add the example to https://bugs.ruby-lang.org/issues/14259?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PR, you can then specify the right behavior (eql 147138137) and guard it with:

ruby_bug'#13669','2.5'...'2.5.1'do
...

Comment threadcore/integer/pow_spec.rb Outdated
it "returns a complex number when negative and raised to a fractional power" do
(-8).pow(1.0/3) .should be_close(Complex(1, 1.73205), TOLERANCE)
(-8).pow(Rational(1, 3)).should be_close(Complex(1, 1.73205), TOLERANCE)
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we share the 1-argument spec with Integer#**?
Or is it difficult?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Planned to do this in a separate PR, but OK, will make it here

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@andrykonchin
andrykonchin merged commit a6453bf into ruby:masterJan 2, 2018
@andrykonchin
andrykonchin deleted the integer-pow-accepts-modulo-argument branch January 2, 2018 12:57

describe "Integer#**" do
it_behaves_like :integer_exponent, :**
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently there is Fixnum#** and Bignum#** specs, but it sounds best to follow the 2.4 unified Integer structure.
I filed an issue to address this in general: #578.

@eregon

Copy link
Copy Markdown
Member

This looks great, thank you for the new specs!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@andrykonchin@eregon