0

0

如何正确使用 BigDecimal 构造函数避免精度断言失败

聖光之護

聖光之護

发布时间:2026-02-26 09:48:29

|

867人浏览过

|

来源于php中文网

原创

如何正确使用 BigDecimal 构造函数避免精度断言失败

本文详解 BigDecimal 双精度浮点数构造函数引发的精度陷阱,揭示为何 new BigDecimal(2.55) 与 new BigDecimal("2.55") 在 JUnit 断言中行为迥异,并提供安全、可靠的初始化实践方案。

本文详解 `bigdecimal` 双精度浮点数构造函数引发的精度陷阱,揭示为何 `new bigdecimal(2.55)` 与 `new bigdecimal("2.55")` 在 junit 断言中行为迥异,并提供安全、可靠的初始化实践方案。

在金融计算、精确数值比对等场景中,BigDecimal 是 Java 中保障高精度运算的首选类型。然而,一个极易被忽视的细节——构造方式的选择——会直接导致单元测试意外失败,甚至引发生产环境中的隐性精度错误。

核心问题在于:BigDecimal 提供了多个构造函数,但语义截然不同。尤其当传入 double 类型参数时(如 new BigDecimal(2.55)),其行为并非“将数字 2.55 精确表示为 BigDecimal”,而是将该 double 值的二进制浮点近似值(即 IEEE 754 表示)转换为 BigDecimal。由于 2.55 在二进制中无法精确表示,它在 double 中实际存储的是一个微小偏差的值(例如 2.54999999999999982236431605997495353221893310546875)。因此:

System.out.println(new BigDecimal(2.55));
// 输出:2.54999999999999982236431605997495353221893310546875

而 new BigDecimal("2.55") 则严格按字符串字面量解析,生成精确等于 2.55 的 BigDecimal

System.out.println(new BigDecimal("2.55"));
// 输出:2.55

回到原始测试用例:

Moshi Chat
Moshi Chat

法国AI实验室Kyutai推出的端到端实时多模态AI语音模型,具备听、说、看的能力,不仅可以实时收听,还能进行自然对话。

下载
  • ✅ assertThat(finalBalance, is(new BigDecimal("2.55"))) 成功:因两边均为精确的 2.55
  • ❌ assertThat(finalBalance, is(new BigDecimal(2.55))) 失败:因右侧是 2.549999...,与计算结果 2.55 不等

值得注意的是,initialBalance 和 spendingOne 使用 int 和 double 构造看似“无害”,实则风险已埋下:

  • new BigDecimal(5) 安全(int → 精确)
  • new BigDecimal(0.25) 不安全!虽然 0.25 在二进制中可精确表示(0.01₂),但此属特例;换成 0.1 或 0.2 就立即暴露问题。

推荐的安全初始化方式(按优先级排序):

  1. 始终首选 String 构造函数
    明确、可控、无歧义:

    BigDecimal amount = new BigDecimal("123.45");
  2. 使用 BigDecimal.valueOf(double)
    内部先将 double 转为 String 再构造,对常见十进制数更友好(但仍有边界情况需注意):

    BigDecimal amount = BigDecimal.valueOf(2.55); // 实际调用 valueOf(255, 2)
  3. 避免直接使用 new BigDecimal(double)
    JDK 文档明确警告:“The results of this constructor can be somewhat unpredictable.” —— 其行为高度依赖 double 的底层表示,应视为已过时且危险的 API。

? 额外建议:

  • 在团队代码规范中明文禁止 new BigDecimal(double);
  • 使用静态分析工具(如 SonarQube、ErrorProne)配置规则拦截该构造函数调用;
  • 对金额、利率等关键字段,考虑封装工厂方法强制校验输入格式(如仅接受 String 或 long + scale)。

精度不是“差不多就行”,而是“必须分毫不差”。选择正确的 BigDecimal 构造方式,是从第一行代码就守护业务准确性的关键防线。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
软件测试常用工具
软件测试常用工具

软件测试常用工具有Selenium、JUnit、Appium、JMeter、LoadRunner、Postman、TestNG、LoadUI、SoapUI、Cucumber和Robot Framework等等。测试人员可以根据具体的测试需求和技术栈选择适合的工具,提高测试效率和准确性 。

452

2023.10.13

java测试工具有哪些
java测试工具有哪些

java测试工具有JUnit、TestNG、Mockito、Selenium、Apache JMeter和Cucumber。php还给大家带来了java有关的教程,欢迎大家前来学习阅读,希望对大家能有所帮助。

311

2023.10.23

Java 单元测试
Java 单元测试

本专题聚焦 Java 在软件测试与持续集成流程中的实战应用,系统讲解 JUnit 单元测试框架、Mock 数据、集成测试、代码覆盖率分析、Maven 测试配置、CI/CD 流水线搭建(Jenkins、GitHub Actions)等关键内容。通过实战案例(如企业级项目自动化测试、持续交付流程搭建),帮助学习者掌握 Java 项目质量保障与自动化交付的完整体系。

23

2025.10.24

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

850

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

638

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

218

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1560

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

643

2023.11.24

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

320

2026.02.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号