[python] Python float to int conversion

Basically, I'm converting a float to an int, but I don't always have the expected value.

Here's the code I'm executing:

x = 2.51

print("--------- 251.0")
y = 251.0
print(y)
print(int(y))

print("--------- 2.51 * 100")
y = x * 100
print(y)
print(int(y))

print("--------- 2.51 * 1000 / 10")
y = x * 1000 / 10
print(y)
print(int(y))

print("--------- 2.51 * 100 * 10 / 10")
y = x * 100 * 10 / 10
print(y)
print(int(y))

x = 4.02
print("--------- 402.0")
y = 402.0
print(y)
print(int(y))

print("--------- 4.02 * 100")
y = x * 100
print(y)
print(int(y))

print("--------- 4.02 * 1000 / 10")
y = x * 1000 / 10
print(y)
print(int(y))

print("--------- 4.02 * 100 * 10 / 10")
y = x * 100 * 10 / 10
print(y)
print(int(y))

And here's the result (first value is the result of the operation, second value is int() of the same operation):

--------- 251.0
251.0
251
--------- 2.51 * 100
251.0
250
--------- 2.51 * 1000 / 10
251.0
251
--------- 2.51 * 100 * 10 / 10
251.0
250
--------- 402.0
402.0
402
--------- 4.02 * 100
402.0
401
--------- 4.02 * 1000 / 10
402.0
401
--------- 4.02 * 100 * 10 / 10
402.0
401

2.51 and 4.02 are the only values that lead to that strange behaviour on the 2.50 -> 5.00 range. Every other two digits value in that range converts to int without any problem when given the same operations.

So, what am I missing that leads to those results? I'm using Python 2.7.2 by the way.

This question is related to python floating-point int

The answer is


int converts by truncation, as has been mentioned by others. This can result in the answer being one different than expected. One way around this is to check if the result is 'close enough' to an integer and adjust accordingly, otherwise the usual conversion. This is assuming you don't get too much roundoff and calculation error, which is a separate issue. For example:

def toint(f):
    trunc = int(f)
    diff = f - trunc

    # trunc is one too low
    if abs(f - trunc - 1) < 0.00001:
        return trunc + 1
    # trunc is one too high
    if abs(f - trunc + 1) < 0.00001:
        return trunc - 1
    # trunc is the right value
    return trunc

This function will adjust for off-by-one errors for near integers. The mpmath library does something similar for floating point numbers that are close to integers.


2.51 * 100 = 250.999999999997

The int() function simply truncates the number at the decimal point, giving 250. Use

int(round(2.51*100)) 

to get 251 as an integer. In general, floating point numbers cannot be represented exactly. One should therefore be careful of round-off errors. As mentioned, this is not a Python-specific problem. It's a recurring problem in all computer languages.


>>> x = 2.51
>>> x*100
250.99999999999997

the floating point numbers are inaccurate. in this case, it is 250.99999999999999, which is really close to 251, but int() truncates the decimal part, in this case 250.

you should take a look at the Decimal module or maybe if you have to do a lot of calculation at the mpmath library http://code.google.com/p/mpmath/ :),


Languages that use binary floating point representations (Python is one) cannot represent all fractional values exactly. If the result of your calculation is 250.99999999999 (and it might be), then taking the integer part will result in 250.

A canonical article on this topic is What Every Computer Scientist Should Know About Floating-Point Arithmetic.


What Every Computer Scientist Should Know About Floating-Point Arithmetic

Floating-point numbers cannot represent all the numbers. In particular, 2.51 cannot be represented by a floating-point number, and is represented by a number very close to it:

>>> print "%.16f" % 2.51
2.5099999999999998
>>> 2.51*100
250.99999999999997
>>> 4.02*100
401.99999999999994

If you use int, which truncates the numbers, you get:

250
401

Have a look at the Decimal type.


Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to floating-point

Convert list or numpy array of single element to float in python Convert float to string with precision & number of decimal digits specified? Float and double datatype in Java C convert floating point to int Convert String to Float in Swift How do I change data-type of pandas data frame to string with a defined format? How to check if a float value is a whole number Convert floats to ints in Pandas? Converting Float to Dollars and Cents Format / Suppress Scientific Notation from Python Pandas Aggregation Results

Examples related to int

How can I convert a char to int in Java? How to take the nth digit of a number in python "OverflowError: Python int too large to convert to C long" on windows but not mac Pandas: Subtracting two date columns and the result being an integer Convert bytes to int? How to round a Double to the nearest Int in swift? Leading zeros for Int in Swift C convert floating point to int Convert Int to String in Swift Converting String to Int with Swift