You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何分步与单行调用Math.round保留两位小数结果不同?需强制转换?

为什么分步保留两位小数与单行写法结果存在差异?

我在尝试寻找将小数保留两位小数的简便方法时,编写了如下代码:

double n = 123.4567, o = 123.4567, p = 123.4567;
n *= 100;
n = Math.round(n);
n = n / 100;

System.out.println(n);

System.out.println(Math.round(o * 100) / 100);

System.out.println(((double) Math.round(p * 100)) / 100);

运行后输出为:

123.46
123
123.46

我认为第一种分步实现与第二种单行实现的算法逻辑完全一致,仅写法不同,但二者结果却存在差异。为何单行写法需要添加强制类型转换,而分步写法则无需转换?


原因解析

核心问题出在Java的类型转换规则和整数/浮点数除法的区别上,结合Math.round()的返回值特性来看:

  • Math.round(double)的返回值是long类型,不是double。
  • 分步写法的关键:
    1. n *= 100后,n仍是double类型(值为12345.67);
    2. 执行n = Math.round(n)时,因为n是double类型变量,Java会自动把long类型的返回值(12346)转换为double类型(12346.0)再赋值给n;
    3. 最后n / 100是double与int的除法,结果为浮点数(12346.0 / 100 = 123.46)。
  • 单行写法Math.round(o * 100) / 100的问题:
    1. Math.round(o * 100)返回long类型的12346;
    2. 这里是long与int的整数除法,Java会直接舍弃小数部分,计算结果为123(12346 ÷ 100 = 123)。
  • 第三种写法通过(double) Math.round(p * 100),把long类型的12346强制转换为double类型的12346.0,后续除法变为浮点数运算,因此得到正确的123.46。

简言之:分步写法中,赋值给double变量的操作自动完成了类型转换;单行写法直接用long做整数除法,自然得不到预期的浮点数结果。


内容的提问来源于stack exchange,提问作者Brandon Luu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:02:13