Python和C#中的按位左移

use*_*982 0 c# python bit-manipulation

为什么Python和C#中的按位左移有不同的值?

蟒蛇:

    >>> 2466250752<<1
    4932501504L
Run Code Online (Sandbox Code Playgroud)

C#:

    System.Console.Write((2466250752 << 1).ToString()); // output is 637534208
Run Code Online (Sandbox Code Playgroud)

Jon*_*art 6

您在C#中溢出了32位(无符号)整数.

在python中,所有整数都是任意大小的.这意味着整数将扩展到所需的任何大小.请注意,我添加了下划线:

>>> a = 2466250752
>>>
>>> hex(a)
'0x9300_0000L'     
>>>
>>> hex(a << 1)
'0x1_2600_0000L'
   ^-------------- Note the additional place
Run Code Online (Sandbox Code Playgroud)

在C#中,uint只有32位.向左移动时,超出整数的大小,导致溢出.

换班前:

在此输入图像描述

转移后:

在此输入图像描述

请注意,a没有1python显示的前导.


要解决此情况的限制,您可以使用ulong64位而不是32位.这适用于最高2 64 -1的值.


Ada*_*cin 5

Python确保您的整数不会溢出,而C#允许溢出(但在检查的上下文中溢出时抛出异常).实际上,这意味着您可以将Python整数视为具有无限宽度,而C#intuint总是4个字节.

请注意,在Python示例中,值"4932501504L"具有尾随L,表示长整数.Python long在int值中发生溢出时,会自动执行长整数(可用内存大小,与C#不同,这是8个字节)整数.你可以在PEP 237中看到这个想法背后的基本原理.

编辑:要在C#中获取Python结果,您不能使用普通intlong- 这些类型的大小有限.BigInteger是一种大小仅受内存限制的类型.这将是慢intlong算术,所以我不建议使用它在每一个应用程序,但它可以派上用场.

例如,您可以编写与C#中几乎相同的代码,结果与Python相同:

Console.WriteLine(new BigInteger(2466250752) << 1);
// output is 4932501504
Run Code Online (Sandbox Code Playgroud)

这适用于任意的班次大小.例如,你可以写

Console.WriteLine(new BigInteger(2466250752) << 1000);
// output is 26426089082476043843620786304598663584184261590451906619194221930186703343408641580508146166393907795104656740341094823575842096015719243506448572304002696283531880333455226335616426281383175835559603193956495848019208150304342043576665227249501603863012525070634185841272245152956518296810797380454760948170752
Run Code Online (Sandbox Code Playgroud)

当然,这会溢出很长时间.