【问题标题】:How do I prevent integer overflow when using C or C++?使用 C 或 C++ 时如何防止整数溢出?
【发布时间】:2011-10-22 21:28:41
【问题描述】:

http://ideone.com/hANuZ

#include <stdio.h>
int main(int argc, char *argv[]) {
    /**
     * Prints out powers of 2 for 32 iterations.
     */
    int iterations = 0;
    int value = 1;
    while (iterations <= 32) {
        // Prints in this format: iterations    2^n    value
        printf("%d\t2^%d\t%d", iterations, iterations, value);
        switch (iterations) {
          case 8:
          case 16:
          case 32:
              printf("\t\t%d bit\n", iterations);
              break;
          default:
              printf("\n");
              break;
        }
      value *= 2;
      ++iterations;
    }
    return 0;
}

当我编译和运行这段代码时,当我打印大于 2^30 的“值”时,会发生奇怪的事情,即使我将它声明为无符号长。

我该怎么办?我只是一个初学者。 :-(

【问题讨论】:

  • 实际上,这运行了 33 次迭代
  • 可能是因为我使用了++迭代?
  • hmm.... 0-32 = 33。你初始化为 0 并循环直到它

标签: c++ c debugging integer overflow


【解决方案1】:

您正在打印它,就像它是一个有符号整数一样。尝试使用格式字符串

"%u\t2^%u\t%u"

检查您的 printf 文档以了解所有格式代码及其作用。 %u 用于 unsigned int。 unsigned long一般为%lu

【讨论】:

  • 这在第 31 次迭代中去掉了 2^31 上的 - 符号
  • 只有最后一个可能是%u 前两个是变量iterations 可能是%d 好吧
  • @Sweetgirl17,第 32 次迭代。您的第一次迭代是 0,因此当 iterations 为 31 时,您处于第 32 次迭代。
  • 所以对于 32 位整数,值的范围是 -2^31 .. 2^31-1。对于 32 位无符号整数,范围是 0 .. 2^32-1。 -2^31 是有符号位序列 1 000....00(第一位为 1,其他均为 0)。但是,当解释为无符号时,该序列恰好是 2^31,这就是删除“-”的原因。
【解决方案2】:

简单的答案是尝试将其声明为大于 32 位的unsigned long long(根据标准,最少 64 位,谢谢@caf)。

在处理特定大小很重要的类型时,您应该使用已知大小的类型,例如int64_t。

【讨论】:

  • unsigned long long肯定大于 32 位:要求至少为 64 位。
  • @caf:我认为它必须大于long。塔。
  • 它只需要等于或大于long,并且至少64位。 long 和 long long 都是 64 位符合标准,实际上在 64 位 POSIX 系统上很常见。
  • @caf:感谢您的澄清。我已编辑以包含您的信息。
【解决方案3】:

如果您需要整数精度,则需要使用外部库来处理更大的数字。对于 C GMP http://gmplib.org/ 是一个众所周知的库。如果您不需要整数精度,只需使用浮点数或双精度即可。

如果您对类型的限制基于什么感到好奇,可以阅读此页面http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/data_types.html。

【讨论】:

    【解决方案4】:

    只是为了好玩,为了清楚起见,我确实对您的代码示例进行了一些修改

    #include <stdio.h>
    
    int bitcount(unsigned long i) {
       int count = 0;
       while (i > 0) {
          count++;
          i>>=1;
       }
       return count;
    }
    
    int main(int argc, char *argv[]) {
       /**
        * Prints out powers of 2 for 32 iterations.
        */
       int iterations = 0;
       int value = 1;
       while (iterations <= 32) {
          // Prints in this format: iterations    2^n    value
          printf("%d\t2^%u\t%u\t\t%d bit\n", iterations+1, iterations, value, bitcount(value));
          value *= 2;
          ++iterations;
       }
       return 0;
    }
    

    您会注意到127 是8 bit 而256 是9 bit。这是因为

    127 =   1000 0000
    256 = 1 0000 0000
    

    另外,2^32 是 0 因为

    2^32 = 1 0000 0000 ... 0000 0000       (overflow for int)
         =   0000 0000 ... 0000 0000 = 0   (only the first 32 bits are preserved)
    

    【讨论】:

      猜你喜欢
      • 2022-06-22
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 2020-11-06
      • 2021-05-25
      • 2021-10-01
      • 2022-11-25
      • 2021-07-21
      相关资源
      最近更新 更多