15

我知道,C 标准对它进行了很好的定义,它(unsigned)-1必须产生 2^n-1,即所有位都设置的无符号整数。也是如此(uint64_t)-1ll。但是,我在 C11 标准中找不到指定如何(uint64_t)-1解释的内容。

所以,问题是:C 标准中是否有任何保证,以下哪项是正确的?

(uint64_t)-1 == (uint64_t)(unsigned)-1   //0x00000000ffffffff
(uint64_t)-1 == (uint64_t)(int64_t)-1    //0xffffffffffffffff
4

4 回答 4

14

是的。请参阅 C11 6.3.1.3 有符号和无符号整数:

1 当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则不变。

2 否则,如果新类型是无符号的,则在新类型可以表示的最大值的基础上反复加减一,直到值在新类型的范围内。60)

3 否则,新类型是有符号的,值不能在其中表示;结果是实现定义的,或者引发了实现定义的信号。

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

案例 2 适用,因此 -1 以 0x10000000000000000 为模减少为 0xffffffffffffffff。

于 2013-08-18T21:19:04.270 回答
5

表达式1-1具有类型int。转换为 时uint64_t,适用加减 2 n直到值在范围内的原则,因此结果始终为 2 n -1,在本例中 n=64。因此,(uint64_t)-1总是 2 64 -1..

表达式的(int64_t)-1计算结果为 -1,因此同样的推理适用于表达式(uint64_t)(int64_t)-1,它也总是计算为 2 64 -1。

另一方面,(unsigned)-1是类型的正值unsigned int,可以是 2 16 -1、2 32 -1、2 64 -1 或各种其他值,具体取决于编译平台。这些值在转换为 时可能不会产生 2 64uint64_t -1 。

于 2013-08-18T21:13:37.600 回答
1

我猜您正在写作(uint64_t)-1,而不是-1ULL因为您不想对unsigned long long?的大小做出假设 如果是这样,那很好。但是,还有一个尚未提及的替代方案(实际上并没有回答您的问题),但可以通过回避问题来省去很多担忧:

替代

一个好习惯是始终使用UINT64_C(x)而不是(uint64_t)x. 这是一个定义的宏,<stdint.h>它会根据需要自动附加UULULL。因此,根据您的目标,UINT64_C(-1)解析为-1U-1UL或。-1ULL这保证始终正常工作。

类型转换的危险

请注意,(uint64_t)x实际上通常甚至无法正常工作。例如,

(uint64_t)2147483648                // RISKY

由于值 2147483648 (2^31) 太大而无法放入 32 位整数,因此会在某些编译器上生成警告,并且以下内容甚至无法远程工作:

(uint64_t)1000000000000000000       // RISKY

但是,如果您UINT64_C()改为使用,那么一切都是金色的:

UINT64_C(2147483648)                // GOOD

UINT64_C(1000000000000000000)       // GOOD

UINT64_C(-1)                        // GOOD

笔记:

  • _C后缀代表“常数”。</li >
  • 对于<stdint.h>有符号和无符号值,还有 8 位、16 位和 32 位版本。
  • 对于 –1 的特殊情况,您也可以只写UINT64_MAX.
于 2015-08-08T04:01:56.133 回答
-6

这是一个可以用几行代码来回答的问题。

#include <stdio.h>

main()
{
    int          x;
    unsigned int y;

    x = -1;
    printf("\n0x%08x", x);

    y = (unsigned int) -1;
    printf("\n0x%08x", y);

}

在 Eclipse/Microsoft C 编译器上运行此代码会产生:

0xffffffff
0xffffffff

一个类似的程序可以向您展示uint64_t产生了什么。

最后,如果您了解计算机如何使用 2 的补码来添加数字,那么您就会明白,对于任意位数(8、32、64 等)的字,-1 对于字中的每个字节总是全是 ff/双字等

于 2013-08-18T21:24:21.107 回答