From 248f4e7fdb6b9a43e587d332d3bfec36aad480a2 Mon Sep 17 00:00:00 2001 From: tompng Date: Sun, 18 May 2025 00:27:48 +0900 Subject: [PATCH 1/2] Implement Integer.sqrt for large integers Implement Intege.sqrt algorithm used in CRuby (Newton's method) https://github.com/ruby/ruby/pull/10274 --- spec/tags/core/integer/sqrt_tags.txt | 1 - src/main/ruby/truffleruby/core/integer.rb | 12 +++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) delete mode 100644 spec/tags/core/integer/sqrt_tags.txt diff --git a/spec/tags/core/integer/sqrt_tags.txt b/spec/tags/core/integer/sqrt_tags.txt deleted file mode 100644 index 9afa69c3fa4e..000000000000 --- a/spec/tags/core/integer/sqrt_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Integer.sqrt returns the integer square root of the argument diff --git a/src/main/ruby/truffleruby/core/integer.rb b/src/main/ruby/truffleruby/core/integer.rb index f0058d21bcbb..1f0f34b1c3fd 100644 --- a/src/main/ruby/truffleruby/core/integer.rb +++ b/src/main/ruby/truffleruby/core/integer.rb @@ -350,7 +350,17 @@ def self.try_convert(obj) def self.sqrt(n) n = Primitive.rb_to_int(n) raise Math::DomainError if n.negative? - Math.sqrt(n).floor + return Math.sqrt(n).floor if n < 0xfffffffffffff + + shift = n.bit_length / 4 + x = Integer.sqrt(n >> (2 * shift)) << shift + x = (x + n / x) / 2 + xx = x * x + while xx > n + xx -= 2 * x - 1 + x -= 1 + end + x end private def upto_internal(val) From eca9bce6eaef7e2855d7c0af57838454eaf102c0 Mon Sep 17 00:00:00 2001 From: tompng Date: Sun, 18 May 2025 00:34:08 +0900 Subject: [PATCH 2/2] ci check --- src/main/ruby/truffleruby/core/integer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/ruby/truffleruby/core/integer.rb b/src/main/ruby/truffleruby/core/integer.rb index 1f0f34b1c3fd..a105030d5a76 100644 --- a/src/main/ruby/truffleruby/core/integer.rb +++ b/src/main/ruby/truffleruby/core/integer.rb @@ -360,7 +360,7 @@ def self.sqrt(n) xx -= 2 * x - 1 x -= 1 end - x + x + 42 # check if ci is running end private def upto_internal(val)