Побитовый сдвиг - получение разных результатов в C # .net против PHP - PullRequest
1 голос
/ 15 мая 2011

Когда я запускаю эту команду в PHP, я получаю:

Code: 2269495617392648 >> 24
Result: 32

Когда я запускаю ее в C # .net или vb.net, я получаю:

Code: 2269495617392648 >> 24
Result: 135272480

PHPправильно.

Интересно то, что когда я пытаюсь сдвинуть любое число больше, чем int32 в .net, это приводит к плохим результатам ..

Каждое число в int32 (2147483647) даетте же результаты из php и c # .net или vb.net

Есть ли обходной путь для этого в .net?

Ответы [ 2 ]

12 голосов
/ 15 мая 2011

Строго говоря, PHP неправильный.

Полная битовая комбинация числа 2269495617392648:

1000 0001 0000 0001 1000 0010 0000 0001 1000 0001 0000 0000 1000 (2269495617392648)

Если сдвинуть вправо 24 раза, вы получите:

0000 0000 0000 0000 0000 0000 1000 0001 0000 0001 1000 0010 0000 (135272480)

Это битовая комбинация для 135272480, а не 32.

В PHP, очевидно, происходит то, что число 2269495617392648 усекается до 538447880, сохраняя только младшие 32 бита. Обратите внимание, что число 2269495617392648 слишком велико, чтобы поместиться в 32-разрядное целое число со знаком или без знака.

Сдвиг вправо усеченных битов 24 раза дает нам 32.

Before truncation to 32-bits:
1000 0001 0000 0001 1000 0010 0000 0001 1000 0001 0000 0000 1000 (2269495617392648)

After truncation to 32-bits:
0010 0000 0001 1000 0001 0000 0000 1000 (538447880)

Right shifting the truncated bits by 24 bits:
0000 0000 0000 0000 0000 0000 0010 0000 (32)

Вы упомянули эту проблему, когда сказали:

Интересно то, что когда я попытаться сдвинуть любое число больше, чем int32 в .net дает плохие результаты ..

Это дает вам плохие результаты, потому что некоторые биты обрезаются, чтобы уместиться в 32 бита.

Если вы портируете с PHP на C # и хотите сохранить это поведение, вам нужно вручную обрезать биты, используя 2269495617392648 & 0xffffffff вместо просто 2269495617392648 (см. ответ jcomeau_ictx ). Но имейте в виду, что в вашем PHP-коде существует проблема усечения битов. Я не уверен, намеренно это или нет.

3 голосов
/ 15 мая 2011

поразрядно - И ваш номер с 0xffffffff перед сдвигом.

в Python:


>>> 2269495617392648 >> 24
135272480L
>>> (2269495617392648 & 0xffffffff) >> 24
32L

Я редко использую .net, но вполне уверен, что синтаксис будет очень похож.

...