Python:有没有办法阻止从 int 到 long int 的自动转换发生?
考虑这个例子:
>>> from sys import maxint
>>> type(maxint)
<type 'int'>
>>> print maxint
9223372036854775807
>>> type(maxint+2)
<type 'long'>
>>> print maxint+2
9223372036854775809
>>> type((maxint+2)+maxint)
<type 'long'>
>>> print ((maxint+2)+maxint)
18446744073709551616
Python 将从 intautopromote code>,在本例中是一个 64 位整数值(OS X,python 2.6.1)到任意精度的 python
long
整数。尽管类型不相同,但它们很相似,并且 Python 允许使用常用的数字运算符。通常这很有用,例如能够在 32 位机器上使用需要 64 位值的代码。
然而,任意精度运算比本机 int 运算慢得多。例如:
>>> print maxint**maxint # execution so long it is essentially a crash
有没有办法阻止或禁止将 Python int
自动升级为 Python long
?
Consider the example:
>>> from sys import maxint
>>> type(maxint)
<type 'int'>
>>> print maxint
9223372036854775807
>>> type(maxint+2)
<type 'long'>
>>> print maxint+2
9223372036854775809
>>> type((maxint+2)+maxint)
<type 'long'>
>>> print ((maxint+2)+maxint)
18446744073709551616
Python will autopromote from an int
, which in this case is a 64 bit integer value (OS X, python 2.6.1) to a python long
integer which is of arbitrary precision. Even though the types are not the same, they are similar and Python allows the usual numeric operators to be used. Usually this is helpful, for example to be able to use code that expects 64-bit values on a 32-bit machine.
However, the arbitrary precision operations are vastly slower than the native int operations. For example:
>>> print maxint**maxint # execution so long it is essentially a crash
Is there a way to defeat or disallow the auto-promotion of a Python int
to a Python long
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
所以你想抛弃“唯一正确的方法”并在溢出问题上复古。愚蠢的你。
C / C++ / C# / Java 风格的溢出没有什么好处。 它不能可靠地引发错误情况 。对于 C 和 C99,它是 ANSI 和 POSIX 中的“未定义行为”(C++ 要求模数返回),并且是已知的安全风险。你为什么想要这个?
无缝溢出到 long 的 Python 方法 是更好的方法。我相信 Perl 6 也采用了相同的行为。
您可以使用 Decimal 模块 获得更多有限溢出:
您可以使用 Decimal 类设置精度和边界条件,并且溢出几乎是立即的。您可以设置陷阱的内容。您可以设置最大值和最小值。真的——还有什么比这更好的呢? (说实话,我不知道相对速度,但我怀疑它比 numby 更快,但显然比本机整数慢......)
对于您的图像处理的特定问题,这听起来像是考虑某种形式的自然应用程序饱和度算术。您还可以考虑,如果 32 算术发生溢出,请在明显情况下检查操作数:pow、**、*。您可以考虑重载运算符并检查您不需要的条件想。
如果小数、饱和或重载运算符不起作用 - 您可以编写扩展。如果你想抛弃Python的溢出方式来复古的话,天堂会帮助你的......
So you want to throw out the One True Way and go retro on overflows. Silly you.
There is no good upside to the C / C++ / C# / Java style of overflow. It does not reliably raise an error condition. For C and C99 it is "undefined behavior" in ANSI and POSIX (C++ mandates modulo return) and it is a known security risk. Why do you want this?
The Python method of seamlessly overflowing to a long is the better way. I believe this is the same behavior being adapted by Perl 6.
You can use the Decimal module to get more finite overflows:
You can set your precision and boundary conditions with Decimal classes and the overflow is nearly immediate. You can set what you trap for. You can set your max and min. Really -- How does it get better than this? (I don't know about relative speed to be honest, but I suspect it is faster than numby but slower than native ints obviously...)
For your specific issue of image processing, this sounds like a natural application to consider some form of saturation arithmetic. You also might consider, if you are having overflows on 32 arithmetic, check operands along the way on obvious cases: pow, **, *. You might consider overloaded operators and check for the conditions you don't want.
If Decimal, saturation, or overloaded operators don't work -- you can write an extension. Heaven help you if you want to throw out the Python way of overflow to go retro...
如果您希望算术溢出在例如 32 位内溢出,您可以使用例如
numpy.uint32
。当发生溢出时,这会向您发出警告。
不过我测试了它的速度:
它看起来速度不太好。
If you want arithmetic overflows to overflow within e.g. 32 bits, you could use e.g.
numpy.uint32
.That gives you a warning when an overflow occurs.
I tested its speed though:
It's not looking good for speed.
如果您偶尔在算法中包含
num = int(num)
,则可以强制您的值返回正常的int
。如果该值很长但适合本机 int,它将降级为 int。如果该值不适合本机 int,它将保留为 long。You can force your values to return to normal
int
s if you include annum = int(num)
occasionally in your algorithm. If the value is long but fits in a native int, it will demote down to int. If the value doesn't fit in a native int, it will remain a long.Int 与 long 是一个历史遗产 - 在 python 3 中,每个 int 都是一个“long”。如果你的脚本速度受到 int 计算的限制,那么你可能做错了。
为了给您一个正确的答案,我们需要更多关于您想要做什么的信息。
Int vs long is an historical legacy - in python 3, every int is a "long". If your script speed is limited by int computation, it is likely that you are doing it wrong.
To give you a proper answer, we need more information on what are you trying to do.
好吧,如果您不关心准确性,您可以将所有数学运算对 maxint 取模。
Well, if you don't care about accuracy you could all of your math ops modulo maxint.
我不知道它是否会更快,但您可以使用一个元素的 numpy 数组而不是整数。
如果你关心的具体计算是整数求幂,那么我们可以得出一些推论:
I don't know if it would be faster, neccesarily, but you could use numpy arrays of one element instead of ints.
If the specific calculation you are concerned about is integer exponentiation, then there are some inferences we can draw: