Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if float is an integer: is_integer() vs. modulo 1

Tags:

python

I've seen a number of questions asking how to check if a float is an integer. Majority of answers seem to recommend using is_integer():

(1.0).is_integer()
(1.55).is_integer()

I have also occasionally seen math.floor() being used:

import math
1.0 == math.floor(1.0)
1.55 == math.floor(1.55)

I'm wondering why % 1 is rarely used or recommended?

1.0 % 1 == 0
1.55 % 1 == 0

Is there a problem with using modulo for this purpose? Are there edge cases that this doesn't catch? Performance issues for really large numbers?

If % 1 is a fine alternative, then I'm also wondering why is_integer() was introduced to the standard library?

It seems that % is much more flexible. For example, its common to use % 2 to check if a number is odd/even, or % n to check if something is a multiple of n. Given this flexibility, why introduce a new method (is_integer) that does the same thing, or use math.floor, both of which require knowing/remembering that they exist and knowing how to use them? I know that math.floor has uses beyond just integer checking but still...

like image 414
Simon Avatar asked Sep 23 '26 09:09

Simon


2 Answers

All are valid for the purpose. The math.floor option requires exact matching between a specific value and the result of the floor function. Which is not very convenient if you want to encapsulate it in a generic method. So it boils down to the first and third option. Both are valid and will do the job. So the key difference is simple - performance:

from timeit import Timer

def with_isint(num):
    return num.is_integer()
def with_mod(num):
    return num % 1 == 0

Timer(lambda: with_isint(10.0)).timeit(number=10000000)
#output: 2.0617980659008026
Timer(lambda: with_mod(10.0)).timeit(number=10000000)
#output: 2.6560597440693527

Naturally this is a simple operation so you'd need a lot of calls in order to see a considerable difference, as you can see in the example.

like image 61
Alexander Ejbekov Avatar answered Sep 24 '26 23:09

Alexander Ejbekov


One soft reason is definitely: readability

If a function called is_integer() returns True, it is obvious what you have been testing.

However, using the modulo solution, one has to think through the process to see, that it is actually testing if a float is an integer. If you wrap your modulo formalism in a function with an obvious name such as simon_says_its_an_integer(), I think it's just as fine (apart from needlessly introducing an already existing function).

like image 45
G.Brown Avatar answered Sep 24 '26 23:09

G.Brown



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!