Java中整数除法会截断小数,导致45/100得0.0;应使至少一个操作数为浮点型,如progress/100.0或(double)progress/100,避免事后转double,并注意total为0的校验与溢出处理。

这个问题很典型:比如 int progress = 45;,写成 double percentage = progress / 100;,结果永远是 0.0。根本原因不是公式错,而是整数除法在 Java 中会直接截断小数——45 / 100 在 int 范围内算完就是 0,再转 double 也是 0.0。
确保除法在浮点上下文中进行
只要让至少一个操作数是浮点类型,就能避免整数除法提前截断:
- 用浮点字面量:写成
progress / 100.0或progress / 100d - 显式强制转换:写成
(double) progress / 100(注意括号位置,(double)(progress / 100)仍错) - 避免把整数除法结果再赋给 double 变量——运算已结束,补救无效
百分比计算推荐写法
不要依赖“先除后乘”,尤其当分母较大时容易因整数溢出或精度丢失失真:
- 安全写法:
double percentage = (double) part / total * 100; - 若需整数结果且要四舍五入:
int result = (int) Math.round((double) part / total * 100); - 若 total 可能为 0,务必提前校验,否则抛
ArithmeticException
整数运算场景的替代方案
如果坚持只用整数(如嵌入式、性能敏感),可调整计算顺序避免中间截断:
立即学习“Java免费学习笔记(深入)”;
- 先乘后除:
int percentage = part * 100 / total;(但要注意part * 100是否溢出) - 用
Math.multiplyExact(part, 100)捕获溢出,再除以 total - 对小数值敏感的业务(如金融类百分比),直接用
BigDecimal构造字符串再运算
调试时快速定位这类 Bug
遇到百分比恒为 0 或明显偏低,优先检查三处:
- 所有参与除法的变量是否全为 int/long?哪怕只有一边是整数,就触发整数除法
- 是否在除法完成后再转 double?这种“事后补救”无效
- 是否误用了
DecimalFormat的格式化掩盖了底层值为 0 的事实?


















