1/2结果为0,因C/C++/Java等语言中整数除法向零截断,丢弃小数部分;1.0/2得0.5是因浮点字面量触发算术转换,提升为double后按浮点规则计算。

整数除法 1/2 为什么结果是 0
因为 C、C++、Java 等语言中,1 和 2 都是整数字面量,默认类型是 int;两个 int 相除,编译器按整数除法规则执行:截断小数部分,只保留商的整数部分。所以 1/2 的数学结果是 0.5,但整数除法直接丢弃 .5,结果就是 0。
这不是四舍五入,也不是向下取整(floor),而是向零截断(truncation)。比如 -3/2 结果也是 -1,不是 -2。
- 常见错误现象:
float a = 1/2;期望得到0.5,实际赋值的是0,打印出来是0.000000 - 这个行为在 C89/C99/C11 标准中明确定义,不是 bug,是设计如此
- 注意:Python 2 行为相同;Python 3 中
/默认是浮点除法,//才是整除
为什么 1.0/2 就能得出 0.5
1.0 是双精度浮点数字面量(double),参与运算时会触发「通常算术转换」(usual arithmetic conversions):2 被自动提升为 double,整个表达式按浮点规则计算,结果自然为 0.5。
- 等效写法还有:
1/2.0、1.0/2.0、(double)1/2、1/(double)2 - 不要写成
(float)1/2后再赋给double变量——虽然结果对,但多了一次不必要的单精度中间计算,可能损失精度 - 在函数参数或宏定义里容易忽略这点,比如
sin(1/2)实际算的是sin(0),不是sin(0.5)
更安全的写法:显式类型转换优于依赖字面量
靠加 .0 修复看似简单,但在复杂表达式或宏中容易漏掉,比如 (a + b) / c 中只要 a、b、c 全是整数,结果就仍是整除。这时候硬加 .0 不直观,还可能改变运算顺序。
- 推荐用
(double)(a + b) / c或1.0 * (a + b) / c,明确告诉编译器“这里要浮点语义” - 在勒让德多项式这类数值计算中,像
(2 * n - 1) / n这种子表达式如果没转成浮点,整除会直接抹掉小数,导致整个递推崩坏 - GCC/Clang 开启
-Wconversion能捕获隐式整数截断警告,建议开发期启用
容易被忽略的边界点
整数除法的“截断”发生在运算阶段,不是赋值阶段。也就是说,int x = 1; int y = 2; float z = x / y; 依然得 0.0——因为 x / y 在赋值前已经算完了,且是纯整数运算。
- 别指望类型提升发生在赋值右侧整体;它只看每个操作数的类型和运算符规则
- 宏定义里写
#define DIV(a,b) ((a)/(b))是危险的,DIV(1,2)还是0;应写成#define DIV(a,b) ((double)(a)/(b)) - 嵌入式或竞赛代码里,有人用
1e-9 + 1.0 * a / b防止优化器误判,其实没必要;关键是把除法本身拉进浮点域










