C语言中double类型求余方法及整数运算、long范围疑问
问题解答
1. 整数取余公式的工作原理
在C语言中,整数除法会自动截断小数部分(向零取整),不会保留小数位。拿你的例子来说:
a = 12345(long类型),b = 10(int类型)a / b执行的是整数除法,结果是1234(舍去了0.5的小数部分)- 接着
(a / b) * b就是1234 * 10 = 12340,这个值是小于等于a的最大的b的整数倍 - 最后
a - (a / b) * b就得到了a除以b的余数:12345 - 12340 = 5
只有当a能被b整除时,(a / b) * b才会等于a,此时结果为0,否则都会得到非零的余数。
2. 该方法不适用于double类型的原因及替代方案
失效原因
double是浮点数类型,它的除法是精确到小数的浮点除法,不会截断小数部分。比如:
double a = 12345.0; double b = 10.0; double temp = a / b; // 结果是1234.5,不是1234
此时temp * b = 1234.5 * 10 = 12345.0,和a完全相等,相减后结果就是0,自然无法得到余数。
另外,浮点数本身是用二进制近似存储的,对于一些十进制小数(比如0.1)无法精确表示,这也会导致直接用减法计算时出现精度误差。
替代方案
使用C标准库中的fmod()函数,专门用于计算浮点数的余数,头文件是<math.h>。示例代码:
#include <stdio.h> #include <math.h> int main(void) { double a = 12345.5; double b = 10.0; double remain = fmod(a, b); printf("%lf\n", remain); // 输出5.5 return 0; }
fmod(a, b)的计算逻辑是返回a - b * trunc(a/b),和整数取余的逻辑一致,会截断a/b的小数部分后再计算。
3. long类型的取值上限问题
你查到的2147483647是32位有符号int类型的最大值,而long类型的长度是平台相关的:
- 在32位操作系统中,long通常是32位,最大值确实是
2147483647 - 在64位操作系统中,long通常是64位,最大值是
9223372036854775807
你的示例中12345远小于这两个上限,所以代码能正常运行。如果想确认当前平台的long类型范围,可以包含<limits.h>头文件,直接输出LONG_MAX宏的值:
#include <stdio.h> #include <limits.h> int main(void) { printf("long的最大值:%ld\n", LONG_MAX); return 0; }
内容的提问来源于stack exchange,提问作者goldensnub
相关产品推荐
相关产品推荐

