Computing the integer square root of large numbers
Your function is rather unnecessary. When converted to double, all 64-bit integers retain 1 sign bit and at least 52 precision bits. So the error is at most 11 bit; which means for any number N, the error $$dN&lt;=\frac{2^{11}}{2^{63}}N=2^{-52}N$$
With simple calculus, the error of sqrt() is $$d(\sqrt{N})=\frac{dN}{2\sqrt{N}}&lt;=\frac{2^{-52}N}{2\sqrt{N}}=2^{-53}\sqrt{N}&lt;2^{-53}*2^{32}=2^{-21}&lt;&lt;1$$
In any case the error must be smaller than 1. With rounding/truncation, it can only be -1, 0, or 1.

So your code can be

func isqrt(_ n: Int) -&gt; Int {
    var r = Int(Double(n).squareRoot()) // Initial approximation
    if r * r &gt; n { r -= 1 }
    else if (r + 1) * (r + 1) &lt;= n { r += 1}
    return r
}


edit:
There will be time that (r + 1) * (r + 1) be larger than Int.max and causes error. Instead of using multipliedReportingOverflow, I would do it this way

func isqrt(_ n: Int) -&gt; Int {
    if n &gt;= 3037000499 * 3037000499 {return 3037000499}
    var r = Int(Double(n).squareRoot()) // Initial approximation
    if r * r &gt; n { r -= 1 }
    else if (r + 1) * (r + 1) &lt;= n { r += 1}
    return r
}


edit 2:
To deal with different possible Int sizes:

func isqrt(_ n: Int) -&gt; Int {
  #if arch(i386) || arch(arm)
    if n &gt;= 46340 * 46340 {return 46340}
  #else
    if n &gt;= 3037000499 * 3037000499 {return 3037000499}
  #endif

  var r = Int(Double(n).squareRoot()) // Initial approximation
  if r * r &gt; n { r -= 1 }
  else if (r + 1) * (r + 1) &lt;= n { r += 1}
  return r
}