【发布时间】:2014-12-09 19:03:00
【问题描述】:
我正在简单的 C 程序中试验 unsigned int 数据类型和主要方法参数。作为一个实验,我编写了一个程序,它从命令行获取一个 int 数字作为 main 方法的参数,并将该数字与 0 之间的每个整数相加。
例如程序计算 f(n) = (1 + 2 + 3... + n) 当 n > 0 时有效
#include <stdio.h>
#include <stdlib.h>
const unsigned int MAX_NUM = 92681; //Max input that will avoid int overflow later on
unsigned int sum(unsigned int x);
int main(int argc, char *argv[]) {
unsigned int input = atoi(argv[1]);
if (input < 0 || input > MAX_NUM) {
printf("Invalid input! Input must be less than 92682\n");
exit(0); //If input > MAX_NUM, quit program
}
unsigned int result = sum(input);
printf("Sum to %d = %d\n", input, result);
return 0;
}
unsigned int sum(unsigned int x) {
unsigned int sum = 0;
unsigned int y;
for (y = 0; y <= x; y++) {
sum += y;
printf("Current sum:\t%u\n",sum);
}
return sum;
}
我开始注意到的第一件事是当 f(n) > 2147483648 时整数溢出 - 也就是带符号整数的最大值。
我手动找到了我的程序生成的结果有效的最大值(例如,在整数溢出之前)对于有符号整数为 65535,对于无符号整数为 92681。
为有符号整数运行程序产生了预期的结果 - 在 65535 处,由于整数溢出,非常大的正数变成了非常大的负数。
然后我将每个“int”更改为“unsigned int”。尽管发生了整数溢出,就好像整数是有符号的而不是无符号的。
我的问题是 a) 为什么会这样? b)我怎样才能使我的答案可以使用整个无符号整数范围,即从 0 到 (2^32) - 1(因为我不需要负值!)。
非常感谢!
【问题讨论】:
-
高斯提示:n*(n-1)/2.
-
这就是我计算最大值的方式,即。 2^32 = n*(n-1)/2
标签: c int integer-overflow atoi unsigned-integer