BigDecimal和Long表示金额哪个更合适,怎么选择? (1)
面试回答¶
面试官: BigDecimal 和 Long 表示金额,哪个更合适?怎么选?
你:
这得看场景,没有绝对的对错。核心差异就一点:Long 用整数分,快但不支持小数;BigDecimal 支持任意精度小数,但性能有代价。 选型就看你的业务碰不碰小数。
Long 的方案:以分为单位,整数运算
比如金额 12.34 元,存成 1234L。所有加减操作都是整数运算,CPU 执行飞快,完全没有精度问题。但有个前提——你的业务不能出现分以下的单位。比如打折后 12.34 元打 7 折,算出来是 8.638 元,如果用 Long 存分,你就得自己处理进位规则(四舍五入、向上取整),不然小数部分会被直接截断,一分钱对不上账。
电商内部流转、库存扣减、支付流水这些高频场景,只要不涉及复杂乘除,用 Long 一定是最快最省的,数据库里存 BIGINT,索引效率也高。
BigDecimal 的方案:精确小数运算
一旦涉及乘法除法、利率、汇率换算、折扣分摊,就得上 BigDecimal。它能精确表示 0.1,不会出现 double 那种 0.30000000000000004 的乌龙。你可以定义舍入模式,每步计算都可控。代价是运算比 Long 慢几十倍,对象分配多,GC 压力略大,代码写起来也多几行。
实战中通常是混着用:
-
流转 / 存储:用
Long分。接口传1234,数据库存1234,清晰无歧义。 -
计算:遇到乘除、费率计算时,临时把
Long转成BigDecimal,算完再按规则转回Long分,截断舍入一把确定。 -
对外展示:给前端、用户看的时候转成元,
BigDecimal.valueOf(1234L, 2)得到12.34,或者直接字符串。
一句话:加减用 Long 分安全又快,乘除用 BigDecimal 精确可控。系统内部用分走天下,需要小数计算时再请 BigDecimal 出山。
时序图:Long 分 vs BigDecimal 的处理流程
