Java开发手册中为什么禁止使用BigDecimal的equals方法做等值比较已经为什么禁止使用double直接构造BigDecimal

news2024/11/28 10:52:09

场景

阿里Java开发手册嵩山版中明确指出:

1、BigDecimal的等值比较应使用compareTo()方法,而不是equals()方法

equals()方法会比较值和精度(1.0与1.00返回结果为false),而compareTo()则会忽略精度

2、禁止使用构造方法BigDecimal(double)的方式把double值转换为BigDecimal对象

BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常

 

注:

博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主

Java开发手册为什么禁止使用BigDecimal的equals方法做等值比较?

BigDecimal,相信对于很多人来说都不陌生,很多人都知道他的用法,这是一种java.math 包中提供的一种可以用来

进行精确运算的类型。在进行金额表示、金额计算等场景,不能使用 double、float 等类型,而是要使用对精度支持

更好的 BigDecimal。其内部自带了很多方法,如加,减,乘,除等运算方法都是可以直接调用的。除了需要用

BigDecimal 表示数字和进行数字运算以外,代码中还经常需要对于数字进行相等判断。Java开发手册中有说明:

BigDecimal的等值比较应使用compareTo()方法,而不是equals()方法

equals()方法会比较值和精度(1.0与1.00返回结果为false),而compareTo()则会忽略精度。

看下面的示例:

        BigDecimal bigDecimal = new BigDecimal(1);
        BigDecimal bigDecimal1 = new BigDecimal(1);
        System.out.println(bigDecimal.equals(bigDecimal1));//true

        BigDecimal bigDecimal2 = new BigDecimal(1);
        BigDecimal bigDecimal3 = new BigDecimal(1.0);
        System.out.println(bigDecimal2.equals(bigDecimal3));//true

        BigDecimal bigDecimal4 = new BigDecimal("1");
        BigDecimal bigDecimal5 = new BigDecimal("1.0");
        System.out.println(bigDecimal4.equals(bigDecimal5));//false

通过以上代码示例,我们发现,在使用 BigDecimal 的 equals 方法对 1 和 1.0 进行比较的时候,

有的时候是 true(当使用 int、double 定义 BigDecimal 时),有的时候是false(当使用 String 定义 BigDecimal 时)。

查看源码可知,equals会比较标度scale,见源码

 

BigDecimal 一共有以下 4 个构造方法:

BigDecimal(int) 因为是整数,所以标度就是 0

BigDecimal(double) 无论我们使用 new BigDecimal(0.1)还是 new BigDecimal(0.10)定义,他的近似值

都是0.1000000000000000055511151231257827021181583404541015625

这个,那么他的标度就是这个数字的位数,即 55

BigDecimal(long) 因为是整数,所以标度就是 0

BigDecimal(String)  BigDecimal(“1”)和 BigDecimal(“1.0”)的标度不一样

BigDecimal 中提供了 compareTo 方法,这个方法就可以只比较两个数字的值,如果两个数相等,则返回 0。

BigDecimal bigDecimal6 = new BigDecimal("1");

BigDecimal bigDecimal7 = new BigDecimal("1.0000");

System.out.println(bigDecimal6.compareTo(bigDecimal7)); //0

Java开发手册为什么禁止使用double直接构造BigDecimal

Java开发手册中要求 禁止使用构造方法BigDecimal(double)的方式把double值转换为BigDecimal对象

说明:BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常

比如下面,实际存储值为0.10000000149

BigDecimal bigDecimal = new BigDecimal(0.1F);

 

优先推荐入参为String 的构造方法,或使用BigDecimal的valueOf方法,此方法其实内部执行了Double的toString,

而Double的toString按double的实际能表达的精度对尾数进行了截断。

BigDecimal bigDecimal1 = new BigDecimal("0.1");

BigDecimal bigDecimal2 = BigDecimal.valueOf(0.1);

 

Java中doble为什么不精确?

十进制小数转成二进制,一般采用”乘 2 取整,顺序排列”方法,如 0.625 转成二进制的表示为 0.101。

但是,并不是所有小数都能转成二进制,如 0.1 就不能直接用二进制表示,他的二进制是 0.000110011001100...

这是一个无限循环小数。所以,计算机是没办法用二进制精确的表示 0.1 的。也就是说,在计算机中,

很多小数没办法精确的使用二进制表示出来。在 Java 中,使用 float 和 double 分别用来表示单精度浮点数和双精度浮点数。

所谓精度不同,可以简单的理解为保留有效位数不同。采用保留有效位数的方式近似的表示小数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/597836.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FAQ是什么?如何打造一个高效的FAQ页面?

FAQ是英文Frequently Asked Questions的缩写,即“常见问题解答”。FAQ系统是一个集中管理和展示常见问题和答案的工具。 FAQ页面一般放在网站的主菜单或底部导航栏中,通常与“联系我们”、“关于我们”等页面并列。有些网站还会在页面上方或右侧设置“常…

android开发之NDK配置开发

1、打开项目后,一次点击Tools>SDK Manager 2、点击SDK Tools标签页 3、选中NDK(Side by Side)和CMake复选框 4、点击OK 此时系统会显示一个对话框,告诉你NDK软件包占用了多少磁盘空间 5、点击OK 6、安装完成后,点击…

Web3 游戏的用户留存的挑战与机遇:从经济模型与游戏设计谈起

作者:lesleyfootprint.network 在开发和运营 Web3 游戏时,会面临许多挑战,因此有效地应对这些挑战对游戏的成功至关重要。其中一些策略包括在正式发布之前进行全面测试,并持续提供新的游戏玩法和内容,以确保游戏经济系…

二叉树中的链式结构实现

树的概念与结构 线性表:是一种具有n个相同特性的数据元素的有限序列。线性表逻辑上是线性结构,也就是连成的一条直线,但一条直线上的数据元素并不是一定要物理结构连续的。 讲到二叉树之前,我们要先了解一下什么是树,首…

【RocketMQ】RocketMQ标签、过滤及消息重复消费

【RocketMQ】RocketMQ标签、过滤及消息重复消费 文章目录 【RocketMQ】RocketMQ标签、过滤及消息重复消费1. 标签(Tag)1.1 示例 2. 键(Keys)2.1 示例 3. 消息重复消费3.1 示例 参考文档: 官方文档 1. 标签(Tag) Topic 与 Tag 都是业务上用来归类的标识&#xff0c…

Vue学习2

文章目录 引入vue的分析render修改脚手架的默认配置修改步骤 refpropsmixin局部:全局总结 插件(install)总结 scoped案例总结浏览器本地存储保存读取删除清空 组件自定义事件绑定传递数据的两种方式解绑坑this使用原生的总结 全局事件总线消息…

攻防世界 mfw(Git源码泄露与命令执行漏洞)

目录 Git 源码泄露: 1、strpos() 函数 2、assert()函数 3、file_exists() 函数 4、die() 函数 代码审计: 命令执行漏洞: 打开链接 在About里发现网站是使用Git、PHP、Bootstrap搭建的 使用dirsearch扫一下 从结果可以看出确实存在.git …

在Centos7.9中安装postgresql15最新版本_参考官网说明安装---PostgreSQL工作笔记002

现在我要实现利用nifi同步,postgresql中的增量数据,也就是如果postgresql中出现增删改数据的时候,数据要自动同步到我们远程的mysql数据库中. 又难到我了...首先:去安装postgresql在centos7.9中,之所以在centos7.9中又安装了一遍,因为,我的大体思路,是利用postgresql的逻辑复制…

搭建flask后端和微信小程序前端

目录 一、准备工作 (1)我的前端代码 (2)我的后端代码 (3)后端运行成功的截图 (4)前端运行成功的截图 (5)整体运行成功的截图 二、部署后端 &#xff08…

【C++】什么是函数模板/类模板?

文章目录 一、函数模板1.什么是函数模板?2.函数模板格式3.函数模板原理4.函数模板实例化(1)隐式实例化(2)显示实例化 二.类模板1.类模板定义格式2.类模板的实例化 总结 一、函数模板 1.什么是函数模板? 函…

VBA之正则表达式(42)-- 提取代码中变量名称

实例需求:待处理代码段如下所示,现在需要提取其中的变量名称。 Public pFactor As Integer Sub TestCode() Dim reg As New RegExp, a As Workbook Dim ms As VBScript_RegExp_55.MatchCollection Dim m As VBScript_RegExp_55.Match Dim i, j Dim x1, y…

记一次udp服务性能优化经历

目录 概述磁盘io网络io减少重复计算减少内存复制减少互斥锁 概述 手上有个go项目,接收udp信息(主要是syslog和snmp trap)并查询设备信息,将信息结构化(设备ip名称,匹配了什么规则之类的)后发送…

生态系统NPP及碳源、碳汇模拟(土地利用变化、未来气候变化、空间动态模拟)

前言 由于全球变暖、大气中温室气体浓度逐年增加等问题的出现,“双碳”行动特别是碳中和已经在世界范围形成广泛影响。碳中和可以从碳排放(碳源)和碳固定(碳汇)这两个侧面来理解。陆地生态系统在全球碳循环过程中有着…

综述:图像分割

综述 图像分割(segmentation、cut)指的是将数字图像划分成多个图像子区域的过程。 在实际场景中具有诸多重要应用 在广义的图像分割中,传统方法和深度方法对于分割有不同的定义。 传统方法:对于图像进行区域划分,核心问题在于:区…

饿了么太狠:面个高级Java,抖这多硬活、狠活(饿了么面试真题)

前言: 在40岁老架构师尼恩的(50)读者社群中,经常有小伙伴需要面试饿了么、 头条、美团、阿里、京东等大厂。有很多的小伙伴,完成了人生的逆袭,拿到了高端的offer。 最近一个6年经验的小伙伴,年…

linux进程间通信(共享内存)

共享内存,顾名思义就是允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进 程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常为同一段物理内存。进程可 以将同一段物理内存连接到他们自己的地址空间中&#xff0…

win10 编译 openssl

环境:系统win10 编译器:VS2015 准备: 一、openssl下载 官网:www.openssl.org 安装Perl,安装NASM. cmd下运行perl --version得出下面信息就说明安装perl安装成功. nasm --version得出下面信息,说明nasm安装成功 我以vs2015为例: 打开这个终端,之所以打开这个是因…

适合每一个对高光谱技术感兴趣,并想用python进行实践的人

总结了高光谱遥感技术领域的基础原理与核心概念,采用编程语言复现经典数据处理和应用方法,追踪了最新的技术突破,在消化理解、触类旁通之后,用即使是遥感“小白”也容易接受的方式分享给你。 高光谱遥感学习的第一季:提…

HTTP的缓存机制是什么?

HTTP 缓存机制是一种在 Web 开发中常用的技术,它旨在提高性能和减少网络流量。通过缓存,可以避免不必要的网络请求,减少服务器负载,并加快页面加载速度。下面是关于 HTTP 缓存机制的详细介绍。 HTTP 缓存机制的基本原理是将 Web …

LNMP网站框架搭建(yum方式)

目录 一、Nginx的yum安装 1)搭建nginx相关的yum源 2)刷新yum仓库,安装启动nginx服务 二、mysql的 yum 安装 1)卸载一切与mysql有关的包 2)wget mysql相关的yum源 附加:第二种方式(与上…