Skip to content

Commit caee41f

Browse files
committed
[GR-18163] Implement Integer.sqrt for large integers (#3872)
PullRequest: truffleruby/4539
2 parents a227095 + 555028a commit caee41f

File tree

4 files changed

+12
-3
lines changed

4 files changed

+12
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Compatibility:
2525
* Fix `rb_str_locktmp()` and `rb_str_unlocktmp()` to raise `FrozenError` when string argument is frozen (#3752, @andrykonchin).
2626
* Fix Struct setters to raise `FrozenError` when a struct is frozen (#3850, @andrykonchin).
2727
* Fix `Struct#initialize` when mixed positional and keyword arguments (#3855, @andrykonchin).
28+
* Fix `Integer.sqrt` for large values (#3872, @tompng).
2829

2930
Performance:
3031

spec/tags/core/integer/sqrt_tags.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/main/ruby/truffleruby/core/integer.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,17 @@ def self.try_convert(obj)
350350
def self.sqrt(n)
351351
n = Primitive.rb_to_int(n)
352352
raise Math::DomainError if n.negative?
353-
Math.sqrt(n).floor
353+
return Math.sqrt(n).floor if n < 0xfffffffffffff
354+
355+
shift = n.bit_length / 4
356+
x = sqrt(n >> (2 * shift)) << shift
357+
x = (x + n / x) / 2
358+
xx = x * x
359+
while xx > n
360+
xx -= 2 * x - 1
361+
x -= 1
362+
end
363+
x
354364
end
355365

356366
private def upto_internal(val)

test/mri/excludes/TestInteger.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,3 @@
1111
exclude :test_floor, "<-100000000000000000000> expected but was <0>."
1212
exclude :test_pow, "FloatDomainError: Infinity"
1313
exclude :test_round, "<300> expected but was <200>."
14-
exclude :test_square_root, "10**33."

0 commit comments

Comments
 (0)