这段代码中乘法计算结果错误的原因是什么?
问题分析与解决方案
这是整数溢出导致的计算错误,具体原因和解决方法如下:
错误原因
- 32位
unsigned int的最大值是4294967295,而你需要计算的41929587 * 512 = 21467948544远大于这个上限,计算时会发生溢出,最终只保留结果的低32位,也就是你看到的错误值4288079360。 - 换成
int类型后,32位int的最大值是2147483647,同样无法容纳计算结果,有符号整数溢出后会变成负数(补码循环特性),所以出现了-6887936这个错误输出。
解决方案
使用更大位数的整数类型来存储计算结果,同时配合合适的输入输出函数:
修改后的代码示例(使用uint64_t)
#include <stdint.h> #include <stdio.h> #include <stdlib.h> // ... 其他代码 uint64_t i; uint64_t b = 512; // 用strtoull替代atoi,避免大数字输入时溢出 i = strtoull(line, NULL, 10); uint64_t line_bytes = i * b; printf("The size in 512b blocks of the disk /dev/rdsk/c0b0t2d0s0 is %ju\n", i); printf("The size in Bytes of the disk /dev/rdsk/c0b0t2d0s0 is %ju\n", line_bytes);
另一种方案(使用unsigned long long)
如果不想用stdint.h里的类型,也可以用unsigned long long:
#include <stdio.h> #include <stdlib.h> // ... 其他代码 unsigned long long i; unsigned long long b = 512; i = strtoull(line, NULL, 10); unsigned long long line_bytes = i * b; printf("The size in 512b blocks of the disk /dev/rdsk/c0b0t2d0s0 is %llu\n", i); printf("The size in Bytes of the disk /dev/rdsk/c0b0t2d0s0 is %llu\n", line_bytes);
注意点
- 替换
atoi为strtoull:atoi只能处理int范围内的数值,当输入数字超过int上限时会溢出,strtoull可以安全处理64位无符号整数。 - 输出占位符要对应:
uint64_t用%ju,unsigned long long用%llu,避免格式不匹配导致的输出错误。
内容的提问来源于stack exchange,提问作者elbarna
相关产品推荐
相关产品推荐

