避免精度丢失的关键是明确数据语义与底层行为,优先选用合适类型(如long、BigDecimal),禁用float,慎用double,浮点转整数须按业务选舍入方式,警惕long→float/double的精度陷阱。

避免Java基本数据类型转换时的精度丢失,关键不是回避转换,而是清楚每一步的数据语义和底层行为——整数截断、浮点近似、范围绕回都不是bug,而是设计特性。真正要防的是“静默失真”,即结果变了却没报错、没提示、难追溯。
优先用合适类型,减少转换必要性
很多精度问题源于一开始选错了类型:
- 金额、利率、计数器等需精确的场景,直接用 long(单位为分/毫秒) 或 BigDecimal(字符串构造),不走 double → int 这类危险路径
- 避免 float:它只有约6–7位有效数字,
16777217转成 float 就变成16777216.0,已不可逆丢失 - double 虽有15–16位精度,但
0.1 + 0.2 != 0.3是常态,别用它做等值判断或累计求和
浮点转整数:别用 (int) 截断,按业务选取整方式
强制转 int 总是向零截断:(int)3.9 → 3,(int)-3.9 → -3,这和四舍五入、向上取整、向下取整都不同。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 金额换算(元→分):用
(int) Math.round(d * 100),不是(int)(d * 100) - 分页总数:用
(int) Math.floor(total / pageSize) - 门槛达标(如“满3.2件”):用
(int) Math.ceil(d) - 安全兜底:对大数,改用
Math.toIntExact(Math.round(d)),超 int 范围直接抛异常
整型宽化转换:警惕 long → float/double 的精度陷阱
long 可以自动转 float,不是因为“更小能装进更大”,而是因为 float 指数范围更大(±3.4×10³⁸),但尾数只有23位——超过 2²⁴(16777216)的整数就无法精确表示。
立即学习“Java免费学习笔记(深入)”;
-
long x = 16777217; float f = x;→f == 16777216.0f为 true - long → double 在大于 2⁵³(约9×10¹⁵)后也会丢精度
- 若必须转浮点,且需保留整数精度,请先校验:
if (x
字符串 ↔ 数字:避开 double 构造 BigDecimal 的坑
这是金融系统最常踩的雷:
- ❌
new BigDecimal(0.1)→ 实际是0.1000000000000000055511151231257827021181583404541015625 - ✅
new BigDecimal("0.1")→ 精确等于 0.1 - 从数据库、JSON、Excel 读取数字时,优先用字符串中转,再构造 BigDecimal
- 除法必须指定精度和舍入模式:
bd1.divide(bd2, 2, RoundingMode.HALF_UP)

















