C ++ 20是否为“溢出"的有符号整数很好地定义了左移? [英] Does C++20 well-define left shift for signed integers that "overflow"?

查看:160
本文介绍了C ++ 20是否为“溢出"的有符号整数很好地定义了左移?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在当前的C ++标准草案中,左移运算符的定义如下 [ expr.shift] :

E1 << E2的值是唯一值,与E1×2^E2取模2^N相同,其中N是结果类型的宽度.

请考虑具有32位的int E1 = 2^31-1 = 2'147'483'647E2 = 1int.然后,有个与 E1×2^E2 = 4'294'967'294取模2^N = 2^32模数相等的数,即,所有4'294'967'294 + k×2^32数,其中k是任意整数.例如4'294'967'294(k=0)或-2(k=-1).

我不理解这些数字中的唯一值意味着标准的含义.它表示可以由结果数据类型表示的唯一值吗?然后,我假设结果定义为-2.这种解释正确吗?

直到C ++ 20,定义都不同,这种情况将导致未定义的行为.我想这个变化与负号整数的强制性2's补码表示有关.

实际上,现在不再需要E1为非负数.因此,似乎-1 << 1被定义为-2.那也对吗?

解决方案

是否表示可以由结果表示的唯一值 数据类型

是的.与E1×2^E22^N相乘的一组数字是无限的,但是在任何大小为2^N的区间中只有一个值,因此在宽度为N的整数类型中只有一个可表示的值.

如果我们查看"p0907R1 有符号整数是Two的补码"建议,我们发现了一个类似的短语,带有唯一表示",这一点更加清楚:

从有符号到无符号的转换始终是明确定义的:结果 是目标类型的唯一值 ,与 源整数模2 N .

然后,我想将结果定义为-2.这是解释吗 对吗?

在x64上,等效的asm指令为 shlx (逻辑移位左)

我认为更改与强制性2补语有关 负号整数的表示形式.

正确.就像无符号类型的情况一样,现在它们也用数学方式表示等效类(嗯,我不清楚这是多少,因为它们看起来仍然想让一些UB案例保持溢出状态).

In the current C++ Standard Draft, the left shift operator is defined as follows [expr.shift]:

The value of E1 << E2 is the unique value congruent to E1×2^E2 modulo 2^N, where N is the width of the type of the result.

Consider int E1 = 2^31-1 = 2'147'483'647, E2 = 1, and int having 32 bits. Then there is an infinite number of numbers congruent to E1×2^E2 = 4'294'967'294 modulo 2^N = 2^32, namely, all the numbers 4'294'967'294 + k×2^32 where k is an arbitrary integer. Examples are 4'294'967'294 (k=0) or -2 (k=-1).

I don't understand what the Standard means by the unique value out of these numbers. Does it mean the unique value that can be represented by the resulting data type? Then, I suppose the result is defined as -2. Is this interpretation correct?

Until C++20, the definition was different and this case would cause undefined behavior. I suppose the change is related to the mandatory 2's-complement representation of negative signed integers.

In fact, there is now no more requirement for E1 to be non-negative. It therefore seems that -1 << 1 is defined as -2. Is that right as well?

解决方案

Does it mean the unique value that can be represented by the resulting data type

Yes. The set of numbers congruent to E1×2^E2 modulo 2^N is infinite, but there is only one value in any interval of size 2^N, therefore there is only one value representable in an integer type of width N.

If we look in the "p0907R1 Signed Integers are Two’s Complement" proposal we find a similar phrase with "unique representation" which makes this more clear:

Conversion from signed to unsigned is always well-defined: the result is the unique value of the destination type that is congruent to the source integer modulo 2N.

Then, I suppose the result is defined as -2. Is this interpretation correct?

Yes

On x64 the equivalent asm instruction is shlx (logical shift left)

I suppose the change is related to the mandatory 2-complement representation of negative signed integers.

Correct. As was the case with unsigned types, now also signed types they mathematically represent equivalence classes (well, it's not clear to me how much this is true as it looks like they want to still keep some UB cases on overflow).

这篇关于C ++ 20是否为“溢出"的有符号整数很好地定义了左移?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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