我原本以为Python3应该能够处理任意长度的数字,但我遇到的问题是它们看起来并不一致。
在乘以分割之后,我的int似乎已经改变了它的内部表示,并且不再评估为它以前的自我匹配。
我正在使用整数,没有任何小数或分数,但它的行为几乎就像它正在失去舍入的精度......?
我很欣赏有关为什么会发生这种情况的任何见解,如果有什么我应该采取不同的做法。我的代码有变通方法,但由于结果是反直觉的,我很想知道行为背后的原因;)
Python 3.3.2 (default, Jul 30 2013, 00:52:04)
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.28)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 313585730727764141482831584863
>>> a
313585730727764141482831584863
>>> b = a*2
>>> c = b /2
>>> a
313585730727764141482831584863
>>> c
3.1358573072776415e+29
>>> a == c
False
如果我使用地板分割,这似乎有效 -
>>> c = b//2
>>> c
313585730727764141482831584863
>>> a == c
True
Python 2.7似乎也避免了这个场景,将它们保存在longs
>>> a = 313585730727764141482831584863
>>> a
313585730727764141482831584863L
>>> b = a*2
>>> c = b /2
>>> a
313585730727764141482831584863L
>>> c
313585730727764141482831584863L
>>> a == c
True
我很感激任何见解! 谢谢!
答案 0 :(得分:11)
您正在使用真正的除法运算符/
进行除法,始终将导致浮点值。改为使用楼层划分//
来获取整数结果:
>>> a = 313585730727764141482831584863
>>> b = a*2
>>> c = b // 2
>>> a == c
True
您的计算机硬件无法以所需的精度处理浮点值。
另一种方法是使用decimal.Decimal()
values,但这会导致算术运算速度变慢。
在Python 2中,/
运算符 是分区运算符,但是当应用于整数时。要在Python 2中获得相同的行为,请添加:
from __future__ import division
行为发生了变化,因为仅使用整数运算符和使用至少一个float参数之间的区别令人困惑。
换句话说,标准Python 2 /
运算符是来自Python 3 /
除法运算符的不同野兽。当应用于两个整数操作数时,它的行为就像Python 3中的//
floor division运算符一样。但是如果两个操作数中的任何一个都是float,那么它就像/
float division运算符一样不是的。上面的__future__
导入交换了Python 2 /
运算符,用于Python 3中的真正除法运算符。
在反汇编Python字节码时可以看到这一点:
>>> import dis
>>> def olddivision(x, y): return x / y
...
>>> dis.dis(olddivision)
1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 BINARY_DIVIDE
7 RETURN_VALUE
>>> from __future__ import division
>>> def newdivision(x, y): return x / y
...
>>> dis.dis(newdivision)
1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 BINARY_TRUE_DIVIDE
7 RETURN_VALUE
__future__
导入导致Python编译器为除法运算符使用不同的字节码,为BINARY_DIVIDE
交换BINARY_TRUE_DIVIDE
。