C 中的位移不同于 PHP

Bit shifting in C is different from PHP

我有一个关于 C 中的一小段代码使同一段代码在 PHP 中工作的问题,它与位移有关,我无法弄清楚哪里出了问题。

C:

unsigned u = 3910796769;
u += u << 8;
printf("%u\n",u); 
//Result : 52422369

PHP:

$u = 3910796769;
$u += $u << 8;
printf("%u\n",$u);
//Result : 1005074769633

好吧,C 中的 unsigned 是 32 位的,你甚至不能在不触发溢出的情况下移动你提供的数字一次,但你已经将它移动了 8 次并再添加一次,比如将数字乘以 257, 你应该得到结果 mod 2^32 == 4294967296:

unsigned u = 3910796769;
u += u << 8;

这应该是 256*u + u == 257 * u == 1005074769633 ~= 52422369 (mod 4294967296) 你可以测试一下。

[...]
//Result : 52422369  /* correct (mod 2^32) */

PHP 可能使用 64 位整数进行运算,结果适合 64 位。

$u = 3910796769;
$u += $u << 8;
printf("%u\n",$u);
//Result : 1005074769633

但如果你尝试:

#include <stdio.h>
#include <stdint.h>

int main()
{
    uint64_t u = 3910796769;
    u += u << 8;
    printf("%Lu\n", u); 
    //Result : 1005074769633
}

你会得到正确的结果。

在我的例子中,我需要使用特定公式 select 从一个数组中填充 32 位值的元素。 @Eugene Sh 的回答帮助我在 PHP.

中做到了这一点
$u = 3910796769;
$u += $u << 8;
$u = $u & 0xFFFFFFFF
printf("%u\n",$u);
//Result : 52422369