C和C++标准规定,在相同等级的有符号和无符号整数之间的二进制运算中,有符号整数被转换为无符号整数.由此引起的SO有很多问题......让我们称它为奇怪的行为:无符号转换为签名转换,C++隐式转换(有符号+无符号),警告 - 有符号和无符号整数表达式之间的比较,%(mod)与混合符号等
但是这些都没有给出任何理由,为什么标准是这样的,而不是倾向于签署的注册.我确实找到了一位自封的大师,他说这是明显正确的做法,但他也没有给出推理:http://embeddedgurus.com/stack-overflow/2009/08/a-tutorial-on- signed-and-unsigned-integers /.
查看我自己的代码,无论我将有符号和无符号整数组合在一起,我总是需要从unsigned转换为signed.有些地方没关系,但我没有找到一个代码示例,将有符号整数转换为unsigned是有意义的.
什么情况下铸造到无符号的正确的事情呢?为什么标准是这样的?
如果无法表示值,则从无符号转换为签名会导致实现定义的行为.从有符号到无符号的转换总是以无符号的bitsize的幂为模2,因此它总是被很好地定义.
如果每个可能的无符号值都可以在签名类型中表示,则标准转换为签名类型.否则,选择无符号类型.这保证了转换始终是明确定义的.
如注释所示,C++的转换算法是从C继承的,以保持兼容性,这在技术上是C++的原因.
有人建议,标准中定义签名到无符号转换而不是无符号签名转换的决定在某种程度上是任意的,而另一个可能的决定是对称的.但是,可能的转换不是对称的.
在标准所考虑的两个非二进制补码表示中,n位有符号表示可以仅表示2 n -1个值,而n位无符号表示可以表示2 n个值.因此,有符号到无符号的转换是无损的,可以反转(尽管永远不会产生一个无符号值).另一方面,无符号到符号的转换必须将两个不同的无符号值折叠到同一个带符号的结果上.
在评论中,sint = uint > sint_max ? uint - uint_max : uint提出了公式.这合并了值uint_max和0; 两者都被映射到0.即使对于非2s补码表示,这也有点奇怪,但对于2的补码,它是不必要的,更糟糕的是,它需要编译器发出代码以费力地计算这种不必要的混淆.相比之下,标准的有符号无符号转换是无损的,在通常情况下(二进制补码架构),它是无操作的.
| 归档时间: |
|
| 查看次数: |
677 次 |
| 最近记录: |