我在标准中找不到如何将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
最大值。
无符号整数保证了模算术。因此,任何int
值v都转换为unsigned long
值 u,使得u= K*2n+v,其中 K 为 0 或 1,其中n是unsigned long
的值表示位数。换句话说,如果v为负,只需添加 2n。
2 的幂来自C++标准的要求,即整数用纯二进制系统表示。对于n 个值表示位,可能值的数量为 2n。浮点类型没有这样的要求(您可以使用std::numeric_limits
来检查浮点值表示的基数)。
另请注意,为了迎合一些现在过时的平台,以及一种以自己的方式做事的流行编译器,当无符号值不能直接表示为有符号值时,标准将相反的转换保留为未定义的行为。在实践中,在现代系统上,可以告诉所有编译器使反向转换与转换为无符号类型完全相反,例如Visual C++默认这样做。但是,值得记住的是,没有正式的支持,因此可移植代码会导致轻微的(现在现代计算机不必要的)效率低下。