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

这篇具有很好参考价值的文章主要介绍了Java开发手册中为什么禁止使用BigDecimal的equals方法做等值比较已经为什么禁止使用double直接构造BigDecimal。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

场景

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

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

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

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

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

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

注:

博客:
霸道流氓气质的博客_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,见源码

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

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);

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

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

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

BigDecimal bigDecimal1 = new BigDecimal("0.1");

BigDecimal bigDecimal2 = BigDecimal.valueOf(0.1);

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

Java中doble为什么不精确?

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

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

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

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

所谓精度不同,可以简单的理解为保留有效位数不同。采用保留有效位数的方式近似的表示小数。文章来源地址https://www.toymoban.com/news/detail-467411.html

到了这里,关于Java开发手册中为什么禁止使用BigDecimal的equals方法做等值比较已经为什么禁止使用double直接构造BigDecimal的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spark底层为什么选择使用scala语言开发

    基于Scala的语言特性 集成性:Scala 是一种运行在 Java 虚拟机(JVM)上的静态类型编程语言,可以与 Java 代码无缝集成。由于 Spark 涉及到与大量 Java 生态系统的交互,例如 Hadoop、Hive 等,使用 Scala 可以方便地与这些组件进行集成和交互。 函数式编程支持:Scala 是一种面向函数

    2024年02月10日
    浏览(44)
  • 【JAVA】为什么要使用封装以及如何封装

    个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 Java的封装指的是在一个类中将数据和方法进行封装,使其可以保护起来,只能在该类内部访问,而不允许外部直接访问和修改。这是Java面向对象编程的三个基本特性之一,另外两个是继承和多态。在此之前我们已经学

    2024年02月08日
    浏览(43)
  • 为什么要使用零知识证明来开发跨链协议

    在过去的几年当中出现了各种各样的独立公链以及以太坊 Layer 2。 由于在安全性、低成本、快速交易以及开发者和用户社区差异等方面,不同链都具有各自不同的优势,用户在不同链之间切换使用的行为是很常见的。 比起以太坊链,Layer2 以及其他独立公链上的手续费会更加

    2024年01月19日
    浏览(50)
  • Java面试题:为什么HashMap不建议使用对象作为Key?

    HashMap 是一种基于哈希表的动态数据结构,它允许使用任意不可变对象作为键(key)来存储和检索数据。然而,在某些情况下,使用对象作为 HashMap 的键可能会遇到一些问题。   首先,我们需要明确对象作为 HashMap 的键需要满足一些条件: 不可变性:对象的属性不能被修改,

    2024年04月22日
    浏览(36)
  • 为什么越来越多的开发者放弃使用Postman,而选择Apifox

    1、Postman + Swagger + Mock + JMeter 作为一个后端开发,我做的大部分项目一般都是基于 Swagger 来管理 API 文档,基于 Postman 来做接口调试,基于 JMeter 来做接口性能测试,基于 RAP 等工具 Mock API 数据。 2、存在的问题 (1)多系统数据不互通 API设计者、前端开发、后端开发、测试人

    2024年01月20日
    浏览(42)
  • 什么是 Java 中的数据库连接池?为什么使用连接池来管理数据库连接?

    数据库连接池(database connection pool)是在 Java 中用于管理数据库连接的一种技术。它的主要目的是提高数据库连接的重用性和性能。在传统的数据库连接方式中,每次与数据库建立连接时都需要进行一系列的网络通信和身份验证操作,这样的开销较大并且会影响应用程序的性

    2024年02月06日
    浏览(48)
  • Android组件化架构开发--为什么要使用组件化?组件分层?组件路由的简单实现。

    1.1 单工程项目结构 一般我们都是一个业务建一个包 缺点: 各种业务代码混杂在同一个模块里,开发人员在开发、调测过程的效率越来越低,定位某个业务问题,需要在多个业务代码混合的模块中寻找和跳转。 需要了解各个业务的功能,避免代码的改动影响其它业务的功能

    2024年02月10日
    浏览(52)
  • 在Java中使用FileReader.read()进行读取文件时,为什么乱码?两个方法解决

     以上代码是有可能出现代码输出混乱的情况的,输出效果如下: 可能会出现乱码的问题: 原因可能是文件编码与程序读取时使用的编码不一致。在创建 FileReader 对象时,没有指定文件的编码格式,因此默认使用的是系统默认的编码格式。如果文件中包含非系统默认编码格式

    2024年02月03日
    浏览(38)
  • java的springboot框架中使用logback日志框架使用RabbitHandler注解为什么获取不到消费的traceId信息?

    当使用 Logback 日志框架和 RabbitMQ 的 @RabbitHandler 注解时,如果无法获取消费的 traceId 信息,可能是因为在处理 RabbitMQ 消息时,没有正确地将 traceId 传递到日志中。 为了将 traceId 传递到日志中,你可以利用 MDC(Mapped Diagnostic Context)机制。MDC 是一个线程绑定的上下文容器,允许

    2024年02月09日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包