简体   繁体   English

Python和C#中的按位左移

[英]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# intuint始终为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结果,您不能使用普通的intlong这些类型的大小有限。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM