搬砖拼接64位数字,因高32位long未先强转64,导致拼接失败,顺便发现个问题,32位变量左移32位等于原数值。C下位移操作为逻辑位移,全部左移补零后,数值应为零,结果和预期不符,遂查找症结所在。
代码如下:
long i = 512;
i = i << 32;
结果i == 512
作为对比:32次i << 1结果是0
short i = 512;
i = i << 16;
结果i == 0
所以,第一种情况是个特例。
汇编代码上,shl 20h,shl 1,都是shl
经过一系列对比发现:
初始值512不是重点,初始其他值也是一样效果。;
short 左移32也会出问题,char左移32也会出问题,而二者左移对应的16位和8位都不会有问题,所以问题出在左移32?????!!!!(除了64位的long long ,左移32位才不是原数字,64位是)
GCC编译测试
警告:<<操作达到或者超过类型大小
这个warning也很诡异,针对的不是操作数的类型,还是32位。
例如,long 左移32,会提示这个,short左移16,不会提示。
网上资料
基本都是根据结果猜答案的,类型大小模运算都出来了,那你照顾过16位数的感受吗?16位数左移17位为什么不等于左移1位??(后来仔细看了这段,吐槽一下,自己说了不确定其他编译器,然后还下了定论。)
虽然和我的实操结果相同,但是这种拿经验倒推理论的说法还是不敢太认同。所以去查了一下。
英文版资料如下:
类型强转,这也解释了char和short都只有左移32才异常!!!!!!!即使我用(char)i << 32也是徒劳!!!
原文是说你左移超过32这种操作未定义,也就是说,不支持,不确定,可能因你用的编译器不同而不同!既然答案如此,没办法,只能尽量避免这种操作了!!!!
英文资料摘自https://msdn.microsoft.com/en-us/library/336xbhcz.aspx