在C ++ 03中左移有符号整数未定义的行为? [英] Is left-shifting a signed integer undefined behavior in C++03?

查看:112
本文介绍了在C ++ 03中左移有符号整数未定义的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据C ++ 03,5.8 / 2,左移被定义如下:

According to C++03, 5.8/2, left-shifting is defined as follows:


E1 < < E2是E1(被解释为位模式)左移E2位位置;空位是零填充的。如果E1具有无符号类型,则结果的值为E1乘以数量2上升到功率E2,如果E1具有类型unsigned long,则减去模ULONG_MAX + 1,否则为UINT_MAX + 1。

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比较:

What bothers me here is that unsigned types are explicitly mentioned yet signed types are ignored completely. Compare this to 5.8/3 which defines right-shifting:


E1 >> E2的值是E1右移E2位的位置。如果E1具有无符号类型,或者如果E1具有有符号类型和非负值,则结果的值是E1除以数量2上升到功率E2的商的整数部分。如果E1具有签名类型和负值,则生成的值是实现定义的。

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 /明确提到,即使签名保持非负值和签名保持负值也单独提及。

In 5.8/3 both signed and unsigned are explicitly mentioned, even signed holding non-negative and signed holding negative values are mentioned separately.

AFAIK当在C ++标准中未明确定义某个行为时,该行为未定义。我也看过这个问题,但它关注的是C和C ++之间的差异,似乎没有答案

AFAIK when something is not explicitly defined in C++ Standard the behavior is undefined. I've also seen this question, but it focuses on differences between C and C++ and doesn't seem to have an answer everyone would agree upon.

是否将C ++ 03中定义的有符号整数左移?

Is left-shifting a signed integer defined in C++03?

推荐答案

5.8 / 2说,它将其解释为位模式,这只是实现相关的,如果由于某种原因你的实现不使用2的补码,或者如果你的编译器第二猜测你他们不)。 C ++ 11更明确,但是说同样的事情。

5.8/2 says that it interprets it as a bit-pattern, which is only implementation dependent if for some reason your implementation doesn't use 2's complement, or if your compiler second-guesses you (they don't). C++11 is more explicit, but says the same thing.

有符号整数使用所谓的2的补码。基本上,如果你将有符号整数移位1,如果它是正数,低于2 ^(位 - 2),它将工作,如果它是无符号的。如果它超过了但是积极,你将创建一个奇怪的负数,与原始的没有关系。

Signed integers use what's known as 2's complement. Basically if you bit-shift a signed integer by 1, if it's positive and below 2^(bits - 2) it will work as if it were unsigned. If it is above that but positive, you will create a strange negative number that bears no relation to the original. If it is negative to begin with, you'll get possibly a negative, possibly a positive number.

例如,如果我们有一个8位有符号整数表示 - 1:

For instance, if we have an 8-bit signed integer representing -1:

11111111 // -1

如果我们左移,我们最终以

If we left-shift that we end up with

11111110 // -2

但是,假设我们有-120

However, let's say we have -120

10001000  // -120

/ p>

We shall end up with

00010000  // 16


b $ b

显然不正确!

Obviously that is not correct!

继续使用第65条:

01000001  // 65

向左移动,将变为:

10000001  // -127

这相当于-127。

但是,数字16:

00010000 // 16

向左移动

00100000 // 32

你可以看到,它有时工作,有时不,但通常工作,如果你的数字低于2 ^(位-2),有时但不是通常,如果它在上面 - (2 ^(位-2))。也就是说,向左移动1.向左移动2,再取一点。等。

As you can see, it "sometimes works, sometimes doesn't" but usually works if your number is below 2^(bits-2) and sometimes but not usually if it is above -(2^(bits-2)). That is, to shift left by 1. To shift left by 2, take another bit off. Etc.

这篇关于在C ++ 03中左移有符号整数未定义的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆