【问题标题】:Does UINT_MAX have all bits set to 1?UINT_MAX 是否将所有位都设置为 1?
【发布时间】:2017-02-17 11:59:41
【问题描述】:

以前有人问过这个问题,但我仍然很困惑。

我知道

unsigned int a = -1;

应该是UINT_MAX。但这并不是因为 -1 的所有位都已设置。 C11 说

如果新类型是无符号的,则通过重复添加或转换值 比新类型可以表示的最大值减一 直到值在新类型的范围内

所以让我们说UINT_MAX 是 100(我知道它应该大于 2^16-1,但现在让我们忽略它)

unsigned int a = -1; // will be
unsigned int a = -1 + UINT_MAX + 1; // 100 = UINT_MAX  

标准只说UINT_MAX >= 2^16-1。但它是否说它应该是 2^n-1?

C++ 中的答案也不同?

【问题讨论】:

  • 我认为该标准大多未指定(或平台相关)值的确切位表示。那里(已经)有一些非常奇怪的架构。

标签: c++ c language-lawyer


【解决方案1】:

在 C 中,无符号整数的最大值必须采用以下形式1:2N - 1.

因此,值 UINT_MAX 的所有 value 位都将设置为 1。可能存在 padding 位,其值未指定。


1(引自:ISO/IEC 9899:201x 6.2.6.2 整数类型 1)
对于 unsigned char 以外的无符号整数类型,对象表示的位应分为两组:值位和填充位(后者不需要任何一个)。如果有 N 个值位,则每个位应代表 1 和 2N-1 之间的 2 的不同幂,以便该对象type 应该能够使用纯二进制表示来表示从 0 到 2N-1 的值;这应称为值表示。未指定任何填充位的值。

【讨论】:

  • 嗯。我猜你不能为三元计算机编写 C 编译器。
  • 嗯......你可以,它会很烂:P
  • @Mark:你只需要模拟 8-bit-base-2 逐字节溢出。所以基本上:生成的二进制文件必须在 base-2 模拟器中运行。
【解决方案2】:

不,不完全是。

无符号类型可以由值位填充位组成。

对于最大值,值位将始终设置为 1 是正确的,但填充位的具体值留给实现。所以这意味着 UINT_MAX 需要是一个 梅森数。其他要求规定不能小于 65535。

C 和 C++ 在这方面是等价的。

【讨论】:

  • 但这仍然要求 UINT_MAX 必须是 2^n - 1 的形式,对于某些 n >= 16。
  • 确实如此:即梅森数(不一定是素数),大于或等于 65535。
  • 我在 C++14 标准中找不到任何关于具有任何填充位的基本类型的内容。我能看到在[basic.fundamental] 中引用 C 标准的唯一想法是它必须尊重 C 5.2.4.2.1,这是限制部分。
  • 次要吹毛求疵:最好将梅森数的引用澄清为the term is usually reserved for 2^p-1p 素数。虽然 p 经常被推广到每个正整数,但滥用符号。
【解决方案3】:

你说得对,根据转换的定义,-1 转换为 unsigned int 保证为 UINT_MAX。它与任何位模式无关。如果存在 UINT_MAX 为 100 的实现,则 -1 转换为 unsigned int 将为 100。

UINT_MAX 不能为 100 的原因有:一个是因为它必须 ≥ 2^16-1,但这将允许 UINT_MAX = 1,000,000。其次,因为 unsigned int 必须有一个二进制表示,有一些固定的 n 个值位,所以 UINT_MAX = 2^n - 1。

INT_MAX = 2^31 - 1 和 UINT_MAX = 2^31 - 1(不是通常的 2^32 - 1)可能 。在这种情况下,-1 将设置 32 位; -1 转换为 unsigned int 将是 2^31 - 1 并且只设置了 31 位。

【讨论】:

  • Tiny nitpick: -1 in 1+31-bit signed int 设置了 32 位 如果实现使用二进制补码,自 80 年代中期以来几乎所有机器都这样做对于整数,但 6.2.6.2p2 允许个的补码或符号和幅度分别为 31 位和 2 位。
  • @dave_thompson_085:具有 32 位二进制补码有符号整数的系统几乎肯定也有 32 位无符号整数。非人为实现的unsigned 类型的可能值少于相应的有符号类型的唯一原因是硬件仅限于一种有符号算术形式,它不能容纳 2ⁿ 不同的值。跨度>
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 2013-08-26
  • 1970-01-01
  • 2012-10-27
  • 2017-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多