2013-03-25 102 views
0

爲什麼在Python和C#中按位左移有不同的值?在Python和C中按位左移#

的Python:

>>> 2466250752<<1 
    4932501504L 

C#:

System.Console.Write((2466250752 << 1).ToString()); // output is 637534208 
+0

如果你想在C#中的類似行爲,你需要使用BigInteger(任何長度)或長(在這種情況下) – Martheen 2013-03-25 03:14:39

+1

我需要在Python中類似的行爲:) – user2160982 2013-03-25 03:17:24

+0

哦,用2^32-1 – Martheen 2013-03-25 03:21:07

回答

5

Python確保您的整數不會溢出,而C#允許溢出(但會在檢查的上下文中溢出時引發異常)。實際上,這意味着您可以將Python整數視爲無限寬度,而C#intuint始終爲4個字節。

請注意,在您的Python示例中,值「4932501504L」有一個尾隨L,這意味着長整數。當int值發生溢出時,Python會自動執行數學運算(可用存儲器寬度的大小,不像C#的long,它是8個字節)整數。你可以在PEP 237中看到這個想法背後的基本原理。

編輯:要在C#中獲得Python結果,您不能使用普通的intlong - 這些類型的大小有限。一種尺寸僅受內存限制的類型是BigInteger。對於算術,它將比intlong慢,所以我不建議在每個應用程序中使用它,但它可以派上用場。

舉個例子,你可以編寫幾乎相同的代碼在C#中,用相同的結果的Python:

Console.WriteLine(new BigInteger(2466250752) << 1); 
// output is 4932501504 

這適用於任意的變速大小。例如,你可以寫

Console.WriteLine(new BigInteger(2466250752) << 1000); 
// output is 26426089082476043843620786304598663584184261590451906619194221930186703343408641580508146166393907795104656740341094823575842096015719243506448572304002696283531880333455226335616426281383175835559603193956495848019208150304342043576665227249501603863012525070634185841272245152956518296810797380454760948170752 

當然,這會溢出很長時間。

+0

謝謝,但我如何才能在Python上得到C#上的結果? – user2160982 2013-03-25 03:15:24

+0

@ user2160982查看編輯 – 2013-03-25 03:20:45

+0

對於'BigInteger' +1# – 2013-03-25 03:23:10

6

您是溢出 32位(無符號)的整數的C#。

在Python中,所有整數都是任意大小。這意味着整數將擴展到任何需要的大小。注意,我加下劃線:

>>> a = 2466250752 
>>> 
>>> hex(a) 
'0x9300_0000L'  
>>> 
>>> hex(a << 1) 
'0x1_2600_0000L' 
    ^-------------- Note the additional place 

在C#,uint只有32位。當你左移時,你超過了整數的大小,導致溢出。

轉移之前:

enter image description here

移後:

enter image description here

注意a不具備領先1那蟒蛇顯示。


爲了解決這個限制對於這種情況,你可以使用一個ulong這是64位而不是32位。這將適用於高達2 -1的值。

+0

+1表示'當你左屎時'。很好的解釋 – 2013-03-25 03:16:00

+0

@SnakesandCoffee哈,哎呀。固定。 – 2013-03-25 03:17:46