将-1转换为无符号类型

时间:2011-11-21 06:23:17

标签: c++

考虑以下代码来设置 x

的所有位
unsigned int x = -1;

这可移植吗?它似乎至少适用于Visual Studio 2005-2010

4 个答案:

答案 0 :(得分:6)

显然是:

  

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

由于模数的属性,它保证是该类型可能的最大量。

C99也允许:

  

否则,如果newtype是无符号的,则通过重复添加或减去一个超过最大值的值来转换该值。   可以在newtype中表示,直到值在范围内   新类型。 49)

哪个也是最大的数量。


可能的最大数量可能不是所有位都设置。请使用~static_cast<unsigned int>(0)

答案 1 :(得分:6)

引用密集的答案:

我知道这里有很多正确的答案,但我想补充一些引用。我将引用两个标准:C99 n1256草案(免费提供)和C ++ n1905草案(也可免费提供)。这些特殊标准并没有什么特别之处,它们只是免费提供,而且目前最容易找到。

C ++版本:

§5.3.2¶9:根据本段,如果~(type)0是无符号类型,则值(type)保证设置所有位。

  

〜的操作数应具有整数或枚举类型;结果是其操作数的一个补码。执行整体促销。结果的类型是提升的操作数的类型。

§3.9.1¶4:这解释了溢出如何与无符号数一起使用。

  

无符号整数,声明为无符号整数,应遵守算术模2 n 的定律,其中n是该特定整数大小的值表示中的位数。

§3.9.1¶7,加上脚注49:这解释了数字必须是二进制的。由此,我们可以推断~(type)0必须是type中可表示的最大数字(因为它已打开所有位,并且每个位都是加法的。)

  

整数类型的表示应使用纯的值来定义值     二元计算系统 49

     

49)使用二进制数字0和1的整数的位置表示,其中由连续位表示的值是加法的,开始   使用1,并乘以2的连续积分幂,除了位置最高的位。 (改编自美国国民   信息处理系统词典。)

由于算术以2 n 为模,因此保证(type)-1是该类型中可表示的最大值。还保证~(type)0是该类型中可表示的最大值。因此,它们必须是平等的。

C99版本:

C99版本以更紧凑,更明确的方式拼出它。

§6.5.3¶3:

  

〜运算符的结果是其(提升的)操作数的按位补码(即,   当且仅当转换后的操作数中的相应位为时,才会设置结果中的每个位   没有设置)。整数提升在操作数上执行,结果有   推广类型。如果提升类型是无符号类型,则表达式~E是等效的   到该类型中可表示的最大值减去E。

与在C ++中一样,无符号算法保证是模块化的(我认为我现在已经完成了足够的标准挖掘),所以C99标准绝对保证~(type)0 == (type)-1,我们从§6.5.3中知道¶3~(type)0必须设置所有位。

摘要:

是的,它是便携式的。保证unsigned type x = -1;根据标准设置所有位。

脚注:是的,我们讨论的是值位而不是填充位。但是,我怀疑你需要将填充位设置为1。您可以从最近的Stack Overflow问题(link)中看到,GCC被移植到PDP-10,其中long long类型具有单个填充位。在这样的系统上,unsigned long long x = -1;可能不会将该填充位设置为1.但是,如果使用指针强制转换,则只能发现这种情况,而这通常不是可移植的。

答案 2 :(得分:5)

我在阅读这个问题时很草率,并提出了一些可能因此而误导的评论。我会试着澄清这个答案中的困惑。

声明

unsigned int x = -1;

保证将x设置为UINT_MAX,即unsigned int类型的最大值。表达式-1的类型为int,并且它隐式转换为unsigned int。转换(根据值定义,而不是表示)导致目标无符号类型的最大值。

(碰巧转换的语义针对二进制补码系统进行了优化;对于其他方案,转换可能涉及的不仅仅是复制位。)

但问题是设置x的所有位。那么,UINT_MAX表示为全位 - 一位吗?

对于有符号整数有几种可能的表示形式(二进制补码是最常见的,但也可以是“补码”和“符号和大小”)。但是我们正在处理 unsigned 整数类型,因此表示 signed 整数的方式是无关紧要的。

无符号整数需要以纯二进制格式表示。假设表示的所有位都有助于unsigned int对象的值,那么是的,UINT_MAX必须表示为全位 - 一。

另一方面,允许整数类型具有填充位,这些位对表示没有贡献。例如,unsigned int为32位是合法的,但是这些位中只有24位是值位,因此UINT_MAX将是2 * 24-1而不是2 * 32-1。所以在最一般的情况下,你只能说是

unsigned int x = -1;

x的所有位设置为1。

实际上,很少有系统具有整数类型的填充位。因此,在绝大多数系统中,unsigned int的大小为N位,最大值为2 ** N-1,上述声明设置{的所有位{1}}到1。

此:

x

还会将unsigned int x = ~0U; 设置为UINT_MAX,因为无符号类型的按位补码是根据减法定义的。

答案 3 :(得分:2)

<强>小心!

这是实现定义的,因为如何表示负整数,无论​​是两个补码还是什么,都不是由C ++标准定义的。由编制者决定,并且必须正确记录它。

简而言之,它不便携。它可能不会设置x 的所有位。