使用 C 或 C++ 时如何防止整数溢出?

发布于 2024-11-28 17:20:38 字数 824 浏览 0 评论 0原文

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;
}

当我编译并运行这段代码时,打印时会发生奇怪的事情'value' 大于 2^30 后,即使我将其声明为无符号长整型。

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

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;
}

When I compile and run this piece of code, weird stuff happens when I print 'value' after it is larger than 2^30, even when I declare it as an unsigned long.

What do I do? I am simply a beginner. :-(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

滥情空心 2024-12-05 17:20:38

您将其打印为有符号整数。尝试使用格式字符串

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

检查 printf 文档以了解所有格式代码及其用途。 %u 代表unsigned intunsigned long 一般为%lu

You are printing it like it is a signed integer. try using the format string

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

check your printf documentation for all of the formatting codes and what they do. %u is for unsigned int. unsigned long is generally %lu

儭儭莪哋寶赑 2024-12-05 17:20:38

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

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

The simple answer would be to try declaring it as an unsigned long long which is larger than 32 bits (minimum 64 bits according to the standard, thx @caf).

When dealing with types where the specific size is important though, you should use a type with a known size, like int64_t.

飞烟轻若梦 2024-12-05 17:20:38

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

#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;
}

您会注意到 1278 位2569 位。这是因为

127 =   1000 0000
256 = 1 0000 0000

此外,2^320 因为

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

Just for fun, I did modify your code example a little for clarity

#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;
}

You'll notice that 127 is 8 bit and 256 is 9 bit. This is because

127 =   1000 0000
256 = 1 0000 0000

Also, 2^32 is 0 because

2^32 = 1 0000 0000 ... 0000 0000       (overflow for int)
     =   0000 0000 ... 0000 0000 = 0   (only the first 32 bits are preserved)
记忆之渊 2024-12-05 17:20:38

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

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

If you need integer precision you need to use an external library for larger numbers. For C GMP http://gmplib.org/ is a well known library. If you don't need integer precision just use a float or a double.

If you're curious about what the limits are based on for types, this page is an ok read up http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/data_types.html.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文