[英]Bitwise left shift in Python and C#
Why bitwise left shift in Python and C# has different values? 为什么Python和C#中的按位左移具有不同的值?
Python: 蟒蛇:
>>> 2466250752<<1
4932501504L
C#: C#:
System.Console.Write((2466250752 << 1).ToString()); // output is 637534208
You are overflowing the 32-bit (unsigned) integer in C#. 您正在C#中溢出 32位(无符号)整数。
In python, all integers are arbitrarily-sized. 在python中,所有整数都是任意大小的。 That means the integer will expand to whatever size is required. 这意味着整数将扩展为所需的大小。 Note that I added the underscores: 请注意,我添加了下划线:
>>> a = 2466250752
>>>
>>> hex(a)
'0x9300_0000L'
>>>
>>> hex(a << 1)
'0x1_2600_0000L'
^-------------- Note the additional place
In C#, uint
is only 32-bits. 在C#中, uint
只有32位。 When you shift left, you are exceeding the size of the integer, causing overflow. 当您向左移动时,您超出了整数的大小,从而导致溢出。
Before shifting: 换档前:
After shifting: 转移后:
Notice that a
does not have the leading 1
that python showed. 请注意, a
没有python显示的前导1
。
To get around this limitation for this case, you can use a ulong
which is 64 bits instead of 32 bits. 要在这种情况下解决此限制,可以使用64位而不是32位的ulong
。 This will work for values up to 2 64 -1. 这将适用于最大2 64 -1的值。
Python makes sure your integers don't overflow, while C# allows for overflow (but throws an exception on overflow in a checked context). Python确保您的整数不会溢出,而C#允许溢出(但在检查的上下文中,在溢出时会引发异常)。 In practice this means you can treat Python integers as having infinite width, while a C# int
or uint
is always 4 bytes. 实际上,这意味着您可以将Python整数视为具有无限宽度,而C# int
或uint
始终为4个字节。
Notice in your Python example that the value "4932501504L" has a trailing L, which means long integer. 请注意,在您的Python示例中,值“ 4932501504L”具有结尾的L,表示长整数。 Python automatically performs math in long (size-of-available-memory-width, unlike C#'s long
, which is 8 bytes) integers when overflow would occur in int values. 当int值发生溢出时,Python会自动以长整数(不超过C#的long
,它是8字节)来以长整数(可用内存宽度的大小)执行数学运算。 You can see the rationale behind this idea in PEP 237 . 您可以在PEP 237中看到此想法的基本原理。
EDIT: To get the Python result in C#, you cannot use a plain int
or long
- those types have limited size. 编辑:要在C#中获得Python结果,您不能使用普通的int
或long
这些类型的大小有限。 One type whose size is limited only by memory is BigInteger . BigInteger是一种仅受内存限制的类型。 It will be slower than int
or long
for arithmetic, so I wouldn't recommend using it on every application, but it can come in handy. 它会比int
慢或算术long
,因此我不建议在每个应用程序中都使用它,但是它会派上用场。
As an example, you can write almost the same code as in C#, with the same result as in Python: 例如,您可以编写与C#几乎相同的代码,并获得与Python相同的结果:
Console.WriteLine(new BigInteger(2466250752) << 1);
// output is 4932501504
This works for arbitrary shift sizes. 这适用于任意移位大小。 For instance, you can write 例如,您可以编写
Console.WriteLine(new BigInteger(2466250752) << 1000);
// output is 26426089082476043843620786304598663584184261590451906619194221930186703343408641580508146166393907795104656740341094823575842096015719243506448572304002696283531880333455226335616426281383175835559603193956495848019208150304342043576665227249501603863012525070634185841272245152956518296810797380454760948170752
Of course, this would overflow a long. 当然,这将长时间溢出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.