转换 int -> 无符号长 长 是否由标准定义



我在标准中找不到如何将int值转换为unsigned long long的确切规范。指定了各种类似的转换,例如int -> unsigned,unsigned -> int(如果为负,则为UB),无符号长 -> int等。

例如 GCC,-1被转换为0xffffffffffffffff,而不是转换为0x00000000ffffffff。我可以依赖此行为吗?

是的,这是很好的定义,它基本上是将max unsigned long long + 1添加到-1中,这将始终max unsigned long long。这在C++标准草案4.7积分转换部分中有所涉及,其中规定:

如果目标类型是无符号的

,则结果值是与源整数全等的最小无符号整数(模 2n,其中 n 是用于表示无符号类型的位数)。[注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。

它与 C99执行相同的操作,但 C99 标准草案更容易理解,来自第6.3.1.3节有符号和无符号整数

否则,如果新类型是无符号的,则通过重复添加或 比新类型中可以表示的最大值多减 1 直到该值在新类型的范围内。(49)

其中脚注49说:

这些规则描述数学值的算术,而不是给定类型表达式的值。

是的,它被定义:

C++11 § 4.7 [conv.integral]/2 是这样说的:

如果目标类型是无符号的

,则结果值是与源整数全等的最小无符号整数(模 2n,其中 n 是用于表示无符号类型的位数)。

与-1(模2sizeof(unsigned long long))全等的最小无符号整数是可能的unsigned long long最大值。

无符号整数保证了模算术。因此,任何intv都转换为unsigned long值 u,使得u= K*2n+v,其中 K 为 0 或 1,其中nunsigned long的值表示位数。换句话说,如果v为负,只需添加 2n


2 的幂来自C++标准的要求,即整数用纯二进制系统表示。对于n 个值表示位,可能值的数量为 2n。浮点类型没有这样的要求(您可以使用std::numeric_limits来检查浮点值表示的基数)。


另请注意,为了迎合一些现在过时的平台,以及一种以自己的方式做事的流行编译器,当无符号值不能直接表示为有符号值时,标准将相反的转换保留为未定义的行为。在实践中,在现代系统上,可以告诉所有编译器使反向转换与转换为无符号类型完全相反,例如Visual C++默认这样做。但是,值得记住的是,没有正式的支持,因此可移植代码会导致轻微的(现在现代计算机不必要的)效率低下。

最新更新