summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numeric.c6
-rw-r--r--test/ruby/test_integer.rb4
-rw-r--r--version.h2
3 files changed, 10 insertions, 2 deletions
diff --git a/numeric.c b/numeric.c
index 03b336d9b7..41891acf1a 100644
--- a/numeric.c
+++ b/numeric.c
@@ -5844,7 +5844,11 @@ prefix##_isqrt(argtype n) \
while ((t = n/x) < (argtype)x) x = (rettype)((x + t) >> 1); \
return x; \
} \
- return (rettype)sqrt(argtype##_TO_DOUBLE(n)); \
+ rettype x = (rettype)sqrt(argtype##_TO_DOUBLE(n)); \
+ /* libm sqrt may returns a larger approximation than actual. */ \
+ /* Our isqrt always returns a smaller approximation. */ \
+ if (x * x > n) x--; \
+ return x; \
}
#if SIZEOF_LONG*CHAR_BIT > DBL_MANT_DIG
diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb
index dc68b4e7a4..1f820b28e9 100644
--- a/test/ruby/test_integer.rb
+++ b/test/ruby/test_integer.rb
@@ -709,6 +709,10 @@ class TestInteger < Test::Unit::TestCase
assert_equal(x, Integer.sqrt(x ** 2), "[ruby-core:95453]")
end
+ def test_bug_21217
+ assert_equal(0x10000 * 2**10, Integer.sqrt(0x100000008 * 2**20))
+ end
+
def test_fdiv
assert_equal(1.0, 1.fdiv(1))
assert_equal(0.5, 1.fdiv(2))
diff --git a/version.h b/version.h
index 2715555ea3..358336af38 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 7
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 141
+#define RUBY_PATCHLEVEL 142
#include "ruby/version.h"
#include "ruby/internal/abi.h"