The value of E1 << E2 is E1 (interpreted as a bit pattern) left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type,the value of the result is E1 multiplied by the quantity 2 raised to the power E2,reduced modulo ULONG_MAX+1 if E1 has type unsigned long,UINT_MAX+1 otherwise.
这里困扰我的是,未签名的类型是明确提到的,而签名的类型完全被忽略.比较5.8 / 3定义右移:
The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value,the value of the result is the integral part of the quotient of E1 divided by the quantity 2 raised to the power E2. If E1 has a signed type and a negative value,the resulting value is implementation-defined.
在5.8 / 3中,有签名和无符号都被明确提及,即使签署持有非负数和签名持有负值也分别提及.
AFAIK当C标准中未明确定义某些行为未定义时.我也看到了this question,但它集中在C和C之间的差异,似乎没有一个人人都会同意的答案.
在C 03中定义的有符号整数是否左移?
解决方法
签名整数使用所谓的2的补码.基本上,如果你将一个有符号整数移位1,如果它是正的并且低于2 ^(位-2),它将工作,就好像它是无符号的.如果它高于那个但是正数,你将创建一个与原始无关的奇怪的负数.如果开始是负面的,你会得到一个负数,可能是一个正数.
例如,如果我们有一个表示-1的8位有符号整数:
11111111 // -1
如果我们离开了,我们就结束了
11111110 // -2
但是,假设我们有-120
10001000 // -120
我们会结束
00010000 // 16
显然是不正确的!
继续使用号码65:
01000001 // 65
左转,这将变成:
10000001 // -127
相当于-127.
但是,数字16:
00010000 // 16
左移是
00100000 // 32
正如你所看到的,它“有时可以工作,有时不会”,但通常可以使用,如果你的数字低于2 ^(位-2),有时但通常不超过 – (2 ^(位-2)).也就是说,向左移动1.向左移动2,再另一个位.等等.