1. 简介
在日常开发中,我们经常需要将 double
类型的数据转换为字符串,并且去掉小数部分。本文将介绍几种常见的处理方式:
- 一种是直接截断小数部分(truncation)
- 另一种是四舍五入后再转换(rounding)
这两种方式根据使用场景不同,各有优劣,下面一一来看。
2. 使用类型强制转换进行截断
如果我们的 double
值在 int
的范围内,可以简单粗暴地将其强转为 int
类型。这个过程会直接丢弃小数部分,不做任何四舍五入操作。
✅ 这种方式性能极高,比其他方法快大约 10 倍左右。
String truncated = String.valueOf((int) doubleValue);
⚠️ 注意:这种方式只适用于数值在 int
范围内的场景。如果超出范围,强转会得到错误结果。
3. 使用 String.format()
实现四舍五入
String.format()
提供了一种格式化浮点数的方式,第一个参数 "%.0f"
表示保留 0 位小数:
String rounded = String.format("%.0f", doubleValue);
✅ 四舍五入规则采用的是 HALF_UP
模式:小数点后第一位 ≥ 0.5 则向上取整。
❌ 但这种方式性能最差,不推荐用于高频调用场景。
4. 使用 NumberFormat.format()
NumberFormat
是 Java 中用于格式化数字的工具类,相比 String.format()
性能更好,而且支持自定义舍入模式。
默认情况下,它会保留整数部分,并使用 HALF_EVEN
模式进行舍入(即银行家舍入法):
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(0);
String rounded = nf.format(doubleValue);
如果希望使用标准的四舍五入模式(HALF_UP),可以显式设置:
nf.setRoundingMode(RoundingMode.HALF_UP);
String rounded = nf.format(doubleValue);
或者设置为 FLOOR
模式实现截断:
nf.setRoundingMode(RoundingMode.FLOOR);
String truncated = nf.format(doubleValue);
5. 使用 DecimalFormat.format()
DecimalFormat
和 NumberFormat
类似,但它的格式控制更直观,通过构造函数传入格式字符串来定义输出样式。
例如,使用 #,###
表示只输出整数部分并以千分位分隔:
DecimalFormat df = new DecimalFormat("#,###");
df.setRoundingMode(RoundingMode.HALF_UP);
String rounded = df.format(doubleValue);
同样,也可以设置为 FLOOR
实现截断:
df.setRoundingMode(RoundingMode.FLOOR);
String truncated = df.format(doubleValue);
6. 使用 BigDecimal.toString()
对于大数值或高精度要求的场景,推荐使用 BigDecimal
。它在性能上优于 NumberFormat
和 DecimalFormat
,尤其适合处理超出 int
或 long
范围的 double
值。
通过 setScale(0, RoundingMode.HALF_UP)
可以控制是四舍五入还是截断:
double largeDouble = 345_345_345_345.56;
BigDecimal big = new BigDecimal(largeDouble);
big = big.setScale(0, RoundingMode.HALF_UP);
String rounded = big.toString();
⚠️ 注意:BigDecimal
是不可变类,每次操作都需要重新赋值。
7. 小结
本文介绍了将 double
转换为不带小数位的 String
的几种常见方式,分别适用于不同性能和精度要求的场景:
方法 | 是否支持大数 | 性能 | 是否支持舍入控制 |
---|---|---|---|
强制转换为 int | ❌ | ✅✅✅ | ❌ |
String.format() |
✅ | ❌ | ✅ |
NumberFormat |
✅ | ✅ | ✅ |
DecimalFormat |
✅ | ✅ | ✅ |
BigDecimal |
✅ | ✅✅ | ✅✅ |
📌 实际项目中建议根据具体需求选择合适的方式,比如对性能敏感的小数截断场景可以使用 (int)
强转;而需要高精度控制的则推荐 BigDecimal
。
相关示例代码可在 GitHub 项目 中查看。