gpt4 book ai didi

c - 当 R.H.S 在算术运算中有 int 范围外的 negative int 和 unsigned int

转载 作者:太空宇宙 更新时间:2023-11-04 01:18:25 25 4
gpt4 key购买 nike

我为标题道歉,因为我不得不以某种方式找到一个独特的标题。

考虑下面的代码:

#include<stdio.h>
int main(void)
{
int b = 2147483648; // To show the maximum value of int type here is 2147483647
printf("%d\n",b);

unsigned int a = 2147483650;
unsigned int c = a+(-1);
printf("%u\n",c);
}

上述程序在带有 gcc 编译器的 64 位操作系统上运行时的输出是:

-2147483648
2147483649

请看我对案例的理解:

Unsigned int a 超出了signed int 类型的范围。在 R.H.S (-1) 中,由于操作数的类型不同,因此将转换为 unsigned int。将 -1 转换为 unsigned int 的结果是:

-1 + (unsigned int MAX_UINT +1) = unsigned int MAX_UINT = 4294967295.

现在 R.H.S 将是:

unsigned int MAX_UINT + 2147483650

现在看起来它超出了 unsigned int 的范围。我不知道如何从这里开始,看起来即使我继续这个解释我也不会达到经验输出。

请给出正确的解释。

PS:想知道int b = 2147483648怎么变成-2147483648不是我的本意。我刚刚在代码中添加了这一行,所以很明显 2147483650超出了 int 的范围。

最佳答案

2147483648 不是 32 位的 int,它就在 INT_MAX 之上,其值为 2147483647这样的平台。

int b = 2147483648; 是实现定义的。在您的平台上,它似乎执行 32 位环绕,这是典型的二进制补码架构,但 C 标准不保证。

因此 printf("%d\n", b); 输出 -2147483648

其余代码在 32 位系统上完美定义,输出 2147483649 正确且符合预期。事实上,64 位 操作系统在评估步骤中起着非常微妙的作用,但与实际结果基本无关,而实际结果完全由 C 标准定义。

步骤如下:

  • unsigned int a = 2147483650; 不足为奇,a 是一个 unsigned int 并且它的初始化器是一个 intlong intlong long int,具体取决于这些类型中的哪一种至少有 32 个值位。在 Windows 和 32 位 linux 上,它将是 long long int 而在 64 位 linux 上它将是 long int。该值在存储到 unsigned int 变量时被截断为 32 位。

    您可以通过添加以下代码来验证这些步骤:

    printf("sizeof(2147483650) -> %d\n", (int)sizeof(2147483650));
    printf(" sizeof(a) -> %d\n", (int)sizeof(a));
  • 第二个定义 unsigned int c = a+(-1); 经历相同的步骤:

    • c 被定义为一个 unsigned int 并且它的初始值设定项在存储到 c 中时被截断为 32 位。初始化程序是一个附加项:
    • 第一项是 unsigned int,值为 2147483650U
    • 第二项是带括号的表达式,对值为 1int 进行一元否定。因此,正如您正确分析的那样,它是一个值为 -1int
    • 第二项转换为 unsigned int:转换以 232 为模执行,因此值为 4294967295U
    • 然后使用无符号算术执行加法,指定为对 unsigned int 类型的宽度求模,因此结果是一个 unsigned int2147483649U,(6442450945 模 232)
    • unsigned int 值存储到 c 中并使用 printf("%u\n", c); 正确打印为 2147483649.

如果表达式改为 2147483650 + (-1),则计算将以 64 位带符号算术进行,类型为 long int long long int 取决于架构,结果为 2147483649。当存储到 c 时,此值将被截断为 32 位,因此 c 的值与 2147483649 相同。

请注意,上述步骤不依赖于负值的实际表示。它们针对所有架构进行了完全定义,只有 int 类型的宽度很重要。

您可以使用额外代码验证这些步骤。这是一个完整的检测程序来说明这些步骤:

#include <limits.h>
#include <stdio.h>

int main(void) {
printf("\n");
printf(" sizeof(int) -> %d\n", (int)sizeof(int));
printf(" sizeof(unsigned int) -> %d\n", (int)sizeof(unsigned int));
printf(" sizeof(long int) -> %d\n", (int)sizeof(long int));
printf(" sizeof(long long int) -> %d\n", (int)sizeof(long long int));
printf("\n");

int b = 2147483647; // To show the maximum value of int type here is 2147483647
printf(" int b = 2147483647;\n");
printf(" b -> %d\n",b);
printf(" sizeof(b) -> %d\n", (int)sizeof(b));
printf(" sizeof(2147483647) -> %d\n", (int)sizeof(2147483647));
printf(" sizeof(2147483648) -> %d\n", (int)sizeof(2147483648));
printf(" sizeof(2147483648U) -> %d\n", (int)sizeof(2147483648U));
printf("\n");

unsigned int a = 2147483650;
printf(" unsigned int a = 2147483650;\n");
printf(" a -> %u\n", a);
printf(" sizeof(2147483650U) -> %d\n", (int)sizeof(2147483650U));
printf(" sizeof(2147483650) -> %d\n", (int)sizeof(2147483650));
printf("\n");

unsigned int c = a+(-1);
printf(" unsigned int c = a+(-1);\n");
printf(" c -> %u\n", c);
printf(" sizeof(c) -> %d\n", (int)sizeof(c));
printf(" a+(-1) -> %u\n", a+(-1));
printf(" sizeof(a+(-1)) -> %d\n", (int)sizeof(a+(-1)));
#if LONG_MAX == 2147483647
printf(" 2147483650+(-1) -> %lld\n", 2147483650+(-1));
#else
printf(" 2147483650+(-1) -> %ld\n", 2147483650+(-1));
#endif
printf(" sizeof(2147483650+(-1)) -> %d\n", (int)sizeof(2147483650+(-1)));
printf(" 2147483650U+(-1) -> %u\n", 2147483650U+(-1));
printf("sizeof(2147483650U+(-1)) -> %d\n", (int)sizeof(2147483650U+(-1)));
printf("\n");

return 0;
}

输出:

             sizeof(int) -> 4
sizeof(unsigned int) -> 4
sizeof(long int) -> 8
sizeof(long long int) -> 8

int b = 2147483647;
b -> 2147483647
sizeof(b) -> 4
sizeof(2147483647) -> 4
sizeof(2147483648) -> 8
sizeof(2147483648U) -> 4

unsigned int a = 2147483650;
a -> 2147483650
sizeof(2147483650U) -> 4
sizeof(2147483650) -> 8

unsigned int c = a+(-1);
c -> 2147483649
sizeof(c) -> 4
a+(-1) -> 2147483649
sizeof(a+(-1)) -> 4
2147483650+(-1) -> 2147483649
sizeof(2147483650+(-1)) -> 8
2147483650U+(-1) -> 2147483649
sizeof(2147483650U+(-1)) -> 4

关于c - 当 R.H.S 在算术运算中有 int 范围外的 negative int 和 unsigned int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50657287/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com