-
Notifications
You must be signed in to change notification settings - Fork 193
Implement Integer.sqrt for large integers #3872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Implement Integer.sqrt algorithm used in CRuby (Newton's method) ruby/ruby#10274
Thank you for your pull request and welcome to our community! To contribute, please sign the Oracle Contributor Agreement (OCA).
To sign the OCA, please create an Oracle account and sign the OCA in Oracle's Contributor Agreement Application. When signing the OCA, please provide your GitHub username. After signing the OCA and getting an OCA approval from Oracle, this PR will be automatically updated. If you are an Oracle employee, please make sure that you are a member of the main Oracle GitHub organization, and your membership in this organization is public. |
Thank you for signing the OCA. |
Very nice, thank you for porting this optimization and correctness fix to TruffleRuby! |
@andrykonchin Could you integrate this and look if there are some CRuby tests for this and we could remove excludes for them? |
xx -= 2 * x - 1 | ||
x -= 1 | ||
end | ||
x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering how the constant 0xfffffffffffff
was chosen. Is it based on benchmarking results?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Larger is better as long as Math.sqrt(n).floor
returns correct value.
0xfffffffffffff
is 52bit integer and double has 53bit precision.
If n is larger than 0xfffffffffffff == 0x4000000**2-1
, Math.sqrt(n).floor
might not return correct value.
Integer.sqrt(0x4000001**2-1)
should return 0x4000001 - 1
Math.sqrt(0x4000001**2-1).floor
is 0x4000001
Implement Integer.sqrt algorithm used in CRuby (Newton's method)
ruby/ruby#10274
This spec now passes
Calculation
(x + n / x) / 2.0
is always greater or equal tosquare_root(n)
if there is no calculation error.Integer arithmetic
(x + n / x) / 2
is greater thansquare_root(n)
OR equal tosquare_root(n).floor
After
x -= 1 while x*x > n
,x
will be the expected return value ofInteger.sqrt(n)
Newton's method ensures this while loop is executed only a few times. Experimentally, it's executed only once.