4

My code is

if graph == square_grid and type(math.sqrt(nodes)) is not int: 
    print "Your netork can't have that number of nodes" 

Of course this doesn't work because math.sqrt always returns a float. How can I do this?

Felix
  • 61
  • 4

4 Answers4

13

One way is

int(math.sqrt(x)) ** 2 == x
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
7

Because math.sqrt always returns a float, you can use the built in is_integer method

def is_square(x):
    answer = math.sqrt(x)
    return answer.is_integer()

this will return True if x is a square and False if it's not

>>> is_square(25)
True
>>> is_square(14)
False
Ryan Saxe
  • 17,123
  • 23
  • 80
  • 128
  • Hm. Seeing as floating point numbers are imprecise, could it happen that the sqrt() of a square number will end up not being an integer because of rounding errors during the computation? That would make @larsmans's answer better. – millimoose May 07 '13 at 18:54
  • that is a valid point, although I just ran a for loop that would print out all valid squares up to 100,000 using this method, and it didn't miss one. – Ryan Saxe May 07 '13 at 19:04
  • Integers are exactly represented in floating point (they have all zeros after the point). I'm not sure whether `sqrt` is guaranteed to preserve that, though. – Fred Foo May 07 '13 at 19:18
1

try:

math.sqrt(nodes) == int(math.sqrt(nodes))
Christian Geier
  • 2,059
  • 2
  • 21
  • 27
  • this won't work, because of the imprecision of floats. If the difference between `math.sqrt(nodes)` and `int(math.sqrt(nodes))` is larger than `sys.float_info.epsilon` then you're out of luck. – MattDMo May 07 '13 at 19:06
  • do you mean _smaller_ than `sys.float_info.epsilon`? otherwise I'm confused… – Christian Geier May 07 '13 at 19:19
  • Larger. If the difference is larger than the epsilon, the system sees them as not equal, and the expression returns `False`. – MattDMo May 07 '13 at 20:35
0

Using pure maths (no libraries) a square number can be determined in Python as follows:

not n**0.5 % 1

As the square root of a square integer is an integer, this test uses modulo 1 equal to zero to test if the square root is an integer.

For example:

The following will print the first five square numbers:

for i in range(1, 26):
    if not i**0.5 % 1:
        print(i)

Output:

1
4
9
16
25
S3DEV
  • 8,768
  • 3
  • 31
  • 42