开发者

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)
prin开发者_开发知识库t(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.


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.


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.


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.


>>> 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/ :),


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.


To convert to int you should use the int() function:

def myFunction(x, y):
    return int(x / y)

However if x / y is something like 2.8, int() will remove the decimal and convert it to 2. For this you should use the round() function before using int() which looks like this:

def myFunction(x, y):
    return int(round(x / y))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜