Java 存储金额

一、Java如何存储金额

Java 存储金额有两种方式,一般选第二种

  1. 使用long, 精度表示 分 (涉及汇率、税率可能出问题)
  2. 使用 BigDecimal ,同时 MySQL 表字段使用 decimal(p, q)
  • p:总精度,最多 p 位有效十进制数字。

  • q:小数位数,保留 q 位小数。

  • 整数部分最多为 p - q 位。

二、BigDecimal 的经典问题

1. 比较数值不能直接依赖 equals()

equals() 不仅比较数值,还比较小数位数(scale)。

java 复制代码
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");

System.out.println(a.equals(b));    // false
System.out.println(a.compareTo(b)); // 0

使用 compareTo() 比较金额大小

2. 不推荐通过 float / double 构造 BigDecimal

java 复制代码
BigDecimal a = new BigDecimal(0.1);

System.out.println(a);
// 0.1000000000000000055511151231257827021181583404541015625

正确写法:

java 复制代码
// 推荐:使用字符串
BigDecimal a = new BigDecimal("0.1");

// 也可以:使用 valueOf()
BigDecimal b = BigDecimal.valueOf(0.1);

3. BigDecimal 是不可变对象,计算时需要接收返回值

java 复制代码
BigDecimal price = new BigDecimal("100");

price.add(new BigDecimal("20"));

System.out.println(price); // 100

4. 除法可能抛异常 ArithmeticException

java 复制代码
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");

a.divide(b); // 抛出 ArithmeticException

应该指定精度和舍入模式

java 复制代码
BigDecimal result = a.divide(
    b,
    2,
    RoundingMode.HALF_UP
);

System.out.println(result); // 3.33
  • 2:保留两位小数。

  • HALF_UP:常见的四舍五入模式。

封面

相关推荐
脚本自动化开发8 小时前
存储涨价后,磐镭WO5迷你主机值得买吗
后端
Wang's Blog11 小时前
Java 项目实战: 交友项目 - FastDFS:入门案例
java·开发语言·交友
一只爱撸猫的程序猿11 小时前
我看着一个 AI 引擎在 14 天里,从"记忆"走进了"搜索"
人工智能·后端·架构
apcipot_rain11 小时前
C++转Java日记(03)
java·开发语言·c++
皮皮林55111 小时前
Java实现微信扫码登录
java
陈随易13 小时前
纯 Go 写的 JS 引擎,跑分超过了 C 语言的 QuickJS
前端·后端·程序员
Yyyyyy~14 小时前
【Java】Day4Web基础知识
java·spring boot
卷无止境14 小时前
RAGFlow 项目全景报告:从文档解析引擎到 Agent 原生数据库
后端·python
小Z先生15 小时前
我用 Go + 系统 WebView 写了个纯本地 Postman:不装 Electron、不连云端
后端·github
IT_陈寒15 小时前
Redis连接池泄漏那次,我差点把生产环境搞崩了
前端·人工智能·后端