基本上,我将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。
2.51 * 100 = 250.999999999997
int()
函数只是截断小数点的数字,给出250.使用
int(round(2.51*100))
得到251作为整数。通常,无法准确表示浮点数。因此,应该注意舍入误差。如上所述,这不是特定于Python的问题。这是所有计算机语言中反复出现的问题。
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类型。
使用二进制浮点表示(Python为一)的语言不能完全表示所有小数值。如果计算结果为250.99999999999(可能是),则取整数部分将得到250。
关于这个主题的规范性文章是What Every Computer Scientist Should Know About Floating-Point Arithmetic。
>>> x = 2.51
>>> x*100
250.99999999999997
浮点数不准确。在这种情况下,它是250.99999999999999,它实际上接近251,但int()截断小数部分,在本例中为250。
你应该看看Decimal模块,或者你可能需要在mpmath库http://code.google.com/p/mpmath/ :)上做很多计算,
正如其他人所提到的那样,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
库对接近整数的浮点数做了类似的事情。