本文目录一览:
PHP 如何在64位系统让32位的整型左移溢出
可以在64bit系统上把补码处理一下
×手上没装64bit的php所以用Java的64bit的long模拟
public class Test {
public static void main(String[] args) {
int a=8366115;
System.out.println("32bit:"+a);
long n=83661L15;
System.out.println("64bit:"+n);
if(n0x7fffffffL){
n--; n=~n; n=0x7fffffffL; n=-n;
}
System.out.println("64bit处理后:"+n);
}
}
32bit:-1553563648
64bit:2741403648
64bit处理后:-1553563648
如不想移植以上的,PHP还可以直接把数值pack()打包成32bit有符号,再按32bit有符号unpack()一次也能得到需要的负数,不过感觉这样效率不如以上直接计算快..
PHP版 $a = 1; $a = $a
结果:4
说明 是左移,数值型变量,每左移一位,相当于10进制中乘一次2,此题目上左移了两位,相当于乘了两次2:1X2X2 = 4。
php左移:下面的程序结果为什么是176呀?怎么算出来的?
11的二进制是1011
向左移4位就是10110000
然后在转换成10进制
1*2的4次方=16
1*2的5次方=32
1*2的7次方=128
然后在累计16+32+128=176
不懂的可以看10转2进制 2转10进制
php如何实现js的移位运算符
移位包括有符号左移()、有符号右移()、无符号右移(),其中 js 支持三种移位,PHP只支持前两种移位(没查到第三种),恰好需要PHP进行无符号右移,此处实现一下。先看结果
将数字 $a 向右无符号移动 $n 位
[php] view plain copy
function uright($a, $n)
{
$c = 2147483647($n-1);
return $c($a$n);
}
下面是这样做的理由
1、有符号右移的过程
2 1
2在计算机中存储的二进制表示为
000000000 00000000 00000000 00000010
向右移动1位,高位补0
000000000 00000000 00000000 00000001
结果为1
-2 1
负数的存储是以补码的方式存储的(相关知识自行了解),这里简单说明
符号位是 1,-2的表示为
100000000 00000000 00000000 00000010
补码:除符号位外,其他位按位取反,然后 + 1
11111111 11111111 11111111 11111101
11111111 11111111 11111111 11111110
向右移动1位,高位补1
11111111 11111111 11111111 11111111
结果为 -1(转换成10进制后)
注意:移位操作是按照计算机中实际存储的二进制形式进行移动的
2、无符号右移的过程
2 1同上
-2 1
补码右移1位,高位补 0
01111111 11111111 11111111 11111111
结果是 2147483647
无符号右移 n 位,即把所有位向右移动 n 位(有符号右移),然后把前 n 位变成 0。
要把前 n 位变成 0 ,只需要让其跟一个前 n 位是 0,后 32-n 位是 1 的数进行按位与就可以了。
构造前 n 位是 0 后 32-n 位是 1 的数:利用正数有符号右移高位补 0 实现,这里用 2147483647 这个正数实现(当然其他数也可以),这个数在计算机中的存储前面已经说了,是
01111111 11111111 11111111 11111111
利用这个数构造前 n 位是 0 的数,只需将其向右移动 n-1 位就行了
-2 无符号右移 2位的过程
-2右移2位:11111111 11111111 11111111 11111111
构造数: 00111111 11111111 11111111 11111111
按位与: 00111111 11111111 11111111 111111