在C 03中左移一个有符号整数未定义的行为?

前端之家收集整理的这篇文章主要介绍了在C 03中左移一个有符号整数未定义的行为?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
根据C 03,5.8 / 2,左移定义如下:

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中定义的有符号整数是否左移?

解决方法

5.8 / 2说,它将其解释为一个位模式,这仅在实现依赖的情况下,如果由于某些原因,您的实现不使用2的补充,或者如果您的编译器猜测你(他们没有). C 11更为明确,但说同样的话.

签名整数使用所谓的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,再另一个位.等等.

猜你在找的C&C++相关文章