1

What I would like to do in my program is to give the program a very large integer as an input, evaluate its square root, then determine if the square root is an integer. This determines whether the input is a square number. If it is, return the square root, if it is not, return False. My code looks something like this:

n = int(input())
sqrt = n**(1/2)
if sqrt.is_integer():
    return int(sqrt)
else:
    return False

However, this program is not working correctly with very, very large numbers. For example, when n = 170141183460469231731687303715884105727, the calculated square root value is 1.3043817825332783e+19, and sqrt.is_integer() returns True, when I know this number is a prime number and thus its square root cannot be an integer.

If Python cannot support an arbitrarily large float, is there a way to make Python only determine if the square root of an arbitrarily large integer has decimal places? Thanks in advance.

Btw, I have also tried int(sqrt) == sqrt. Same result.

Kdwk
  • 113
  • 5
  • IIRC, `float` can only encode about 2^64 different values. `170141183460469231731687303715884105727` is not one of them. So `n`, in `n**(1/2)` is first rounded. The result is not exactly encode-able either. so it get rounded to a nearby value which happens to be a whole number. It is not _arbitrarily large float,_ that is the issue, is insufficient precision. Given the limited precision of `float`, **all** large `float` are integers. – chux - Reinstate Monica Sep 13 '22 at 13:30
  • 1
    This is an classic XY problem. X: Title: "prevent Python from identifying a very large float as integer" and Y: "give the program a very large integer as an input, evaluate its square root, then determine if the square root is an integer". The real goal is Y. Solving X (or the inability to solve it) is not the real issue. – chux - Reinstate Monica Sep 13 '22 at 13:52
  • 2
    Are you familiar with [`math.isqrt`](https://docs.python.org/3/library/math.html#math.isqrt)? `math.isqrt(n)**2 == n` will tell you whether a nonnegative integer `n` is a square or not (without floating-point being involved at any point). – Mark Dickinson Sep 13 '22 at 14:14
  • 1
    might be worth checking out Sympy as well; in this specific case [`sympy.ntheory.primetest.is_square`](https://docs.sympy.org/latest/modules/ntheory.html#sympy.ntheory.primetest.is_square) seems to do what you want, but it does lots of other useful things – Sam Mason Sep 13 '22 at 14:24
  • @MarkDickinson would you mind posting your solution as an answer? This math.isqrt() worked and I would like to mark it as the answer. Thanks! – Kdwk Sep 13 '22 at 15:09
  • @Kdwk: If the question is "how can I tell whether a Python `int` is a square", then that's a duplicate. See for example https://stackoverflow.com/a/2489540/270986 – Mark Dickinson Sep 13 '22 at 15:25

0 Answers0