Using Ruby 2.5’s new Integer#sqrt method

Atul Bhosale
2 min readFeb 4, 2018

--

Ruby 2.5 was recently released.

Ruby 2.5 has added Integer#sqrt method which returns the integer square root of the non-negative integer.

>> Integer.sqrt(25)
=> 5
>> Integer.sqrt(64)
=> 8
>> Integer.sqrt(64).class
=> Integer

It returns the largest non-negative Integer less than or equal to the square root of n.

>> Integer.sqrt(63)
=> 7
>> Integer.sqrt(64)
=> 8
>> Integer.sqrt(65)
=> 8
>> Integer.sqrt(80)
=> 8
>> Integer.sqrt(81)
=> 9

We do have Math.sqrt(n).floor to do this. why Integer#sqrt(n)?
It is equivalent to Math.sqrt(n).floor except that Math.sqrt(n) return value will differ due to the limited precision value of floating point arithmetic.

>> Integer.sqrt(10 ** 35)
=> 316227766016837933
>> Math.sqrt(10 ** 35).floor
=> 316227766016837952
>> Integer.sqrt(10 ** 46)
=> 100000000000000000000000
>> Math.sqrt(10 ** 46).floor
=> 99999999999999991611392

Jabari Zakiya found that for math applications the Math.sqrt(n).floor method doesn’t accurately compute the integer square root for integers greater than 10 ** 28 which was reported as a bug.

The Integer#sqrt method accepts a parameter “n” i.e. the number of which we want to find the square root. If n is not a integer, it is converted to an integer first and then the square root is returned.

>> Integer.sqrt(25.5)
=> 5
>> Integer.sqrt(5687.5)
=> 75

The method raises an ArgumentError if none of more than one arguments are passed.

>> Integer.sqrt
Traceback (most recent call last):
3: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
2: from (irb):47
1: from (irb):47:in `sqrt'
ArgumentError (wrong number of arguments (given 0, expected 1))
>> Integer.sqrt(25, 2)
Traceback (most recent call last):
3: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
2: from (irb):48
1: from (irb):48:in `sqrt'
ArgumentError (wrong number of arguments (given 2, expected 1))

It raises a Math::DomainError if n is negative.

>> Integer.sqrt(-1)
Traceback (most recent call last):
3: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
2: from (irb):43
1: from (irb):43:in `sqrt'
Math::DomainError (Numerical argument is out of domain - "isqrt")

It raises a TypeError if the argument cannot be coerced to Integer.

>> Integer.sqrt('test')
Traceback (most recent call last):
3: from /home/atul/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
2: from (irb):76
1: from (irb):76:in `sqrt'
TypeError (no implicit conversion of String into Integer)

--

--