[Python-Dev] Deprecating float.is_integer() (original) (raw)

Tim Peters tim.peters at gmail.com
Wed Mar 21 15:02:37 EDT 2018


[David Mertz]

I've been using and teaching python for close to 20 years and I never noticed that x.isinteger() 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.



More information about the Python-Dev mailing list