Python浮动到int转换

基本上,我将float转换为int,但我并不总是有预期的值。

这是我正在执行的代码:

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))

这是结果(第一个值是操作的结果,第二个值是相同操作的int()):

--------- 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和4.02是导致2.50 - > 5.00范围内的奇怪行为的唯一值。当给定相同的操作时,该范围中的每隔两位数值转换为int而没有任何问题。

那么,我错过了什么导致了这些结果呢?顺便说一句,我正在使用Python 2.7.2。

76
投票
2.51 * 100 = 250.999999999997

int()函数只是截断小数点的数字,给出250.使用

int(round(2.51*100)) 

得到251作为整数。通常,无法准确表示浮点数。因此,应该注意舍入误差。如上所述,这不是特定于Python的问题。这是所有计算机语言中反复出现的问题。

31
投票

What Every Computer Scientist Should Know About Floating-Point Arithmetic

浮点数不能代表所有数字。特别是,2.51不能用浮点数表示,并用非常接近它的数字表示:

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

如果你使用int来截断数字,你会得到:

250
401

看看Decimal类型。

10
投票

使用二进制浮点表示(Python为一)的语言不能完全表示所有小数值。如果计算结果为250.99999999999(可能是),则取整数部分将得到250。

关于这个主题的规范性文章是What Every Computer Scientist Should Know About Floating-Point Arithmetic。

7
投票
>>> x = 2.51
>>> x*100
250.99999999999997

浮点数不准确。在这种情况下,它是250.99999999999999,它实际上接近251,但int()截断小数部分,在本例中为250。

你应该看看Decimal模块,或者你可能需要在mpmath库http://code.google.com/p/mpmath/ :)上做很多计算,

1
投票

正如其他人所提到的那样,int通过截断进行转换。这可能导致答案与预期的不同。解决这个问题的一种方法是检查结果是否与整数“足够接近”并相应地进行调整,否则进行通常的转换。这假设你没有得到太多的舍入和计算错误,这是一个单独的问题。例如:

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

此函数将针对近似整数的off-by-one错误进行调整。 mpmath库对接近整数的浮点数做了类似的事情。