[David Mertz]
I've been using and teaching python for close to 20 years and I never noticed that x.is_integer() exists until this thread.
Except it was impossible to notice across most of those years, because it didn't exist across most of those years ;-)
I would say the "one obvious way" is less than obvious.
When it was introduced, it _became_ the one obvious way.
On the other hand, `x == int(x)` is genuinely obvious..
But a bad approach: it can raise OverflowError (for infinite x); it can raise ValueError (for x a NaN); and can waste relative mountains of time creating huge integers, e.g.,
int(1e306) 1000000000000000017216064596736454828831087825013238982328892017892380671244575047987920451875459594568606138861698291060311049225532948520696938805711440650122628514669428460356992624968028329550689224175284346730060716088829214255439694630119794546505512415617982143262670862918816362862119154749127262208
In Python 2, x == math.floor(x) was much better on the latter count, but not in Python 3 (math.floor used to return a float, but returns an int now). As to Serhiy's `not x % 1.0`, after 5 minutes I gave up trying to prove it's always correct. Besides infinities and NaNs, there's also that Python's float mod can be surprising:
(-1e-20) % 1.0 1.0
There isn't a "clean" mathematical definition of what Python's float % does, which is why proof is strained. In general, the "natural" result is patched when and if needed to maintain that x == y*(x//y) + x%y is approximately true. The odd % result above is a consequence of that, and that (-1e-20) // 1.0 is inarguably -1.0.
and it immediately suggests the probably better `math.isclose(x, int(x))` that is what you usually mean.
Even in some of the poor cases Serhiy found, that wouldn't be a lick better. For example, math.isclose(x/5, int(x/5)) is still a plain wrong way to check whether x is divisible by 5.
x = 1e306 math.isclose(x/5, int(x/5)) True x/5 == int(x/5) True int(x) % 5 3
The problem there isn't how "is it an integer?" is spelled, it's that _any_ way of spelling "is it an integer?" doesn't answer the question they're trying to answer. They're just plain confused about how floating point works. The use of `.is_integer()` (however spelled!) isn't the cause of that, it's a symptom.