为什么C ++标准在混合符号的二进制运算中指定带符号的整数强制转换为无符号? [英] Why does C++ standard specify signed integer be cast to unsigned in binary operations with mixed signedness?

查看:86
本文介绍了为什么C ++标准在混合符号的二进制运算中指定带符号的整数强制转换为无符号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C和C ++标准规定,在相同等级的有符号整数和无符号整数之间的二进制运算中,有符号整数将强制转换为无符号。因此,有很多关于SO的问题...让我们称之为奇怪的行为:未签名到已签名的转换 C ++隐式转换(有符号+无符号)警告-有符号和无符号整数表达式之间的比较,< a href = https://stackoverflow.com/questions/12877988/mod-with-mixed-signedness>具有混合签名的%(mod),等等。

The C and C++ standards stipulate that, in binary operations between a signed and an unsigned integer of the same rank, the signed integer is cast to unsigned. There are many questions on SO caused by this... let's call it strange behavior: unsigned to signed conversion, C++ Implicit Conversion (Signed + Unsigned), A warning - comparison between signed and unsigned integer expressions, % (mod) with mixed signedness, etc.

但是这些都没有给出标准为什么要这样发展的任何理由,而不是强制转换为带符号的整数。我确实找到了一个自称是大师的人,他说这显然是对的,但他也没有给出理由: http://embeddedgurus.com/stack-overflow/2009/08/a-tutorial-on-signed-and-unsigned-integers/

But none of these give any reasons as to why the standard goes this way, rather than casting towards signed ints. I did find a self-proclaimed guru who says it's the obvious right thing to do, but he doesn't give a reasoning either: http://embeddedgurus.com/stack-overflow/2009/08/a-tutorial-on-signed-and-unsigned-integers/.

在我自己的代码中,无论我在何处结合有符号和无符号整数,我总是需要从无符号转换为有符号。在有些地方没关系,但是我还没有找到一个简单的代码示例,可以将带符号的整数强制转换为无符号。

Looking through my own code, wherever I combine signed and unsigned integers, I always need to cast from unsigned to signed. There are places where it doesn't matter, but I haven't found a single example of code where it makes sense to cast the signed integer to unsigned.

什么是在正确的情况下铸造为未签名的情况?为什么采用标准的方式?

What are cases where casting to unsigned in the correct thing to do? Why is the standard the way it is?

推荐答案

如果无法将值从无符号转换为带符号,则会导致实现定义的行为代表。从有符号到无符号的转换始终是无符号位大小的幂的模二,因此它总是定义明确的。

Casting from unsigned to signed results in implementation-defined behaviour if the value cannot be represented. Casting from signed to unsigned is always modulo two to the power of the unsigned's bitsize, so it is always well-defined.

如果每个可能的无符号值均为,则标准转换为有符号类型。可在签名类型中表示。否则,将选择无符号类型。

The standard conversion is to the signed type if every possible unsigned value is representable in the signed type. Otherwise, the unsigned type is chosen. This guarantees that the conversion is always well-defined.


  1. 如评论中所示,C ++的转换算法是从C继承来保持兼容性,从技术上来说,这是C ++中如此的原因。

  1. As indicated in comments, the conversion algorithm for C++ was inherited from C to maintain compatibility, which is technically the reason it is so in C++.

已经建议标准中定义有符号转换为无符号转换而不是无符号转换的决定在某种程度上是任意的,并且其他可能的决定是对称的。但是,可能的转换是对称的。

It has been suggested that the decision in the standard to define signed to unsigned conversions and not unsigned to signed conversion is somehow arbitrary, and that the other possible decision would be symmetric. However, the possible conversion are not symmetric.

在标准考虑的两个非2补码表示中, n 位带符号表示形式只能表示2 n -1个值,而 n 位带符号表示形式只能表示2 n 值。因此,有符号到无符号的转换是无损的,并且可以逆转(尽管永远不会产生一个无符号的值)。另一方面,无符号到有符号的转换必须将两个不同的无符号值折叠到相同的有符号结果上。

In both of the non-2's-complement representations contemplated by the standard, an n-bit signed representation can represent only 2n−1 values, whereas an n-bit unsigned representation can represent 2n values. Consequently, a signed-to-unsigned conversion is lossless and can be reversed (although one unsigned value can never be produced). The unsigned-to-signed conversion, on the other hand, must collapse two different unsigned values onto the same signed result.

在注释中,公式 sint = uint> sint_max? uint-uint_max:建议使用uint 。这将值 uint_max 与0合并;两者都映射为0。即使对于非2s补码表示,这也有些奇怪,但是对于2 s补码,则没有必要,更糟的是,它要求编译器发出代码以费力地计算这种不必要的合并。相比之下,该标准的有符号到无符号转换是无损的,并且在通常情况下(2的补码体系结构)是无操作的。

In a comment, the formula sint = uint > sint_max ? uint - uint_max : uint is proposed. This coalesces the values uint_max and 0; both are both mapped to 0. That's a little weird even for non-2s-complement representations, but for 2's-complement it's unnecessary and, worse, it requires the compiler to emit code to laboriously compute this unnecessary conflation. By contrast the standard's signed-to-unsigned conversion is lossless and in the common case (2's-complement architectures) it is a no-op.

这篇关于为什么C ++标准在混合符号的二进制运算中指定带符号的整数强制转换为无符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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