【问题标题】:Why can I operate with int > +32767?为什么我可以用 int > +32767 操作?
【发布时间】:2016-04-21 02:26:12
【问题描述】:

我可以读到 int 范围(有符号)来自 [−32767, +32767] 但我可以说,例如

int a=70000;
int b=71000;
int c=a+b;

printf("%i", c);
return 0;

输出为 141000(正确)。调试器不应该告诉我 “此操作超出范围”或类似内容?

我想这一定是因为我忽略了 C 编程的基础知识,但我目前正在阅读的书籍中没有一本书没有说明这个“问题”。

编辑: 2147483647好像是上限,谢谢。如果总和超过该数字,则结果为负,这是预期的,但如果是减法,例如:2147483649-2147483647=2 结果仍然很好。我的意思是,为什么值 2147483649 正确地用于减法目的(或者至少在我看来)?

【问题讨论】:

  • 如果您打印sizeof(int),这就是您的int 可以存储的字节数。这是一个提示。
  • 你确定这是你机器上 int 的范围吗?尝试使用 sizeof(int) 打印 int 的字节数。
  • 在今天的机器上,int 至少默认为 32 位?
  • 您的int 可能是 4 个字节,足以存储该值。

标签: c++ int range undefined-behavior


【解决方案1】:

在 C++ 中,int至少长 16 位,但在现代硬件上通常为 32 位。您可以写INT_MININT_MAX 并检查自己。

请注意,有符号整数溢出是未定义的行为,不能保证您会收到警告,除非可能出现高编译器警告和调试模式。

【讨论】:

  • 有些实现中 INT_MAX 为 2147483648,但 sizeof(int) 为 1。(在此类机器上,CHAR_BIT 将为 32。)
  • @MartinBonner 好的,是的,严格来说应该除以CHAR_BIT。将答案更改为查看INT_MAX
【解决方案2】:

范围 [−32767, +32767] 是要求的最小范围。允许实现提供更大的范围。

【讨论】:

  • 我想是[-32768, 32767]
  • @erip - 不,这是 16 位二进制补码系统的常见范围。但绝对最小值略小,也允许符号大小和一个补码。
  • 啊,有趣!直到。谢谢你让我诚实。 +1
  • @erip 我认为是[-32768, 32767] 不。见5.2.4.2.1 Sizes of integer types <limits.h>
【解决方案3】:

所有类型都依赖于编译器。 int 曾经是底层硬件的“本机词”,在 16 位系统上意味着 int 是 16 位(导致 -32k 到 +32k 范围)。当 32 位系统开始出现时,int 自然也随之而来,变成了 32 位,可以存储大约 -20 亿到 +20 亿的值。

然而,当 64 位系统出现时,int 的“原生词”并没有出现,我知道没有 64 位系统或编译器将 int 设为 64 位。

参见例如this reference of integer types 了解更多信息。

【讨论】:

    【解决方案4】:

    虽然标准保证int 的大小为 16 位,但它通常实现为 32 位值。

    【讨论】:

      【解决方案5】:

      你误会了。 int 持有 [-32767, +32767] 的标准保证,但允许持有更多。 (特别是,几乎您可能使用的每个编译器都允许范围 [-2147483648, 2147483647])。

      还有一个问题。如果您将分配给 a 和 b 的值设置得更大您仍然可能不会收到任何警告或错误。整数溢出会导致“未定义的行为”,实际上任何事情都可以发生。

      【讨论】:

      • "如果总和超过该数字" ...任何事情都可能发生。请参阅此错误报告,其中 GCC 将循环从 0 转换为 64 到无限循环,该循环覆盖了所有内存,因为循环中存在有符号整数溢出。 gcc.gnu.org/bugzilla/show_bug.cgi?id=33498
      • 2147483647好像是上限了,谢谢。如果总和超过该数字,则结果为负,这是预期的,但如果是减法,例如:2147483649-2147483647=2,结果仍然很好。我的意思是,为什么值 2147483649 正确地用于减法目的(或者至少在我看来)?
      • 你越来越幸运了。 2147483649 溢出,并导致 int 值为 -2147483647。从 应该 中减去 2147483647 会得到 -4294967294,但 会下溢,最终得到 +2。 但是要注意算术溢出是未定义的行为,编译器可能会假设它不会发生 - 当它发生时各种事情都会出错。
      【解决方案6】:

      int 的大小(以及它可以容纳的最大值)取决于编译器和您使用的计算机。不能保证它将有 2 个字节或 4 个字节,但对于 c++ 变量有一个保证的最小大小

      您可以在此页面中查看 c++ 类型的最小大小列表:http://www.cplusplus.com/doc/tutorial/variables/

      【讨论】:

        【解决方案7】:

        如果一个 int 是四个字节,则 unsigned 是 4294967295,最大有符号。 2147483647 并签署分钟。 -2147483648

        unsigned int ui = ~0;
        int max = ui>>1;
        int min = ~max;
        int size = sizeof(max);
        

        【讨论】:

          猜你喜欢
          • 2020-11-30
          • 2013-09-04
          • 1970-01-01
          • 2019-02-28
          • 2013-05-22
          • 2011-03-31
          • 2020-05-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多