你看,ChatGPT都知道优先使用BigDecimal

在这里插入图片描述

不是三婶儿偏执,非要吐槽。家人们,咱就是说,按照基操逻辑谁会把严格金额计算相关的数据使用double类型呢…
“我以为吕布已经够勇猛了,这是谁的部下?”

前几天,一xxx让帮忙写段代码。内容比较常规,就是按照自定义规则自动计算出一些金额数据。楼主想着暂时也不忙,就帮着写写呗。好家伙!不写不知道,当看到他用Double类型定义存储金额时,内心瞬间沸腾了。嗯,真是个小(大)可(傻)爱(逼)…

在这里插入图片描述

咱就是说,金额相关计算第一考虑肯定是确保精准,优选BigDecimal类型呀,Double类型很容易丢失精度的。尤其是金额,一定要严谨!

你看chatgpt都知道优先使用BigDecimal。

在这里插入图片描述

果不其然,这…真是暴风雨的前奏。我发现有好几个业务模块都使用了这些金额数据做运算,多次加减乘除之类的…

好家伙,“海燕啊,你可长点心吧!”。

在这里插入图片描述

那下面楼主就来详细分析一下,为什么更加建议使用BigDecimal。开整!

文章目录

  • 一、BigDecimal类型数据和Double类型
    • 1.1、BigDecimal
    • 1.2、Double和double的区别
      • 1.2.1、double
      • 1.2.2、Double
      • 1.2.3、double和Double之间的关系
  • 二、两种类型数据的适用场景、优缺点
    • 2.1、Double类型
    • 2.2、BigDecimal类型
  • 三、为什么不建议用Double类型计算金额
    • 3.1、Double类型计算精度易丢失
    • 3.2、数值过大会变为科学记数法形式
  • 四、BigDecimal常用方法
    • 4.1、BigDecimal的初始化
    • 4.2、BigDecimal加法
    • 4.3、BigDecimal减法
    • 4.4、BigDecimal乘法
    • 4.5、BigDecimal除法
    • 4.6、BigDecimal比较大小
    • 4.7、BigDecimal工具类

一、BigDecimal类型数据和Double类型

首先,先来了解一下什么是BigDecimal、什么是Double、什么是double。以及Double和double之间有什么关系。

在这里插入图片描述

1.1、BigDecimal

对于什么是BigDecimal,百度百科中这样描述:

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

主要是: 可对超过16位有效位的数进行精确的运算。

1.2、Double和double的区别

1.2.1、double

八大基本数据类型之一,双精度浮点数。

double(双精度浮点型)是计算机使用的一种资料型别。比起单精度浮点数(float),double(双精度浮点数)使用 64 位(8字节) 来储存一个浮点数。 它可以表示十进制的15或16位有效数字,负值取值范围为 -1.7976E+308 到 -4.94065645841246544E-324,正值取值范围为 4.94065645841246544E-324 到 1.797693E+308

1.2.2、Double

Double是基于基本数据类型double的一个封装类,就是我们常用的java.lang.Double。

在这里插入图片描述

1.2.3、double和Double之间的关系

嗯,是有关系,但也不是情侣关系…

在这里插入图片描述

从jdk1.5开始,引入了“自动装箱”、“自动拆箱”的概念,简化了基本数据类型和包装类之间的转化,提高了使用效率。

关于什么是装箱、拆箱。举个栗子:比如我们常用的List就是一个自动装箱、拆箱的体现。

在这里插入图片描述

如图所示,楼主定义了一个Integer类型的list。当往list中放入数据1和2时,会把int类型自动转换为Integer类型,这个过程就是自动装箱。

在这里插入图片描述

反过来说,当从list中取出数据时,会把Integer类型自动转换为int类型,这个过程就是自动拆箱。

自动装箱最大的优点就是:可以直接使用包装类中所有的方法。

我们直接调用即可,方法内部都已经帮我们处理好了。感兴趣的可以看下源码深入了解哈,这里不再过多介绍。
在这里插入图片描述

二、两种类型数据的适用场景、优缺点

2.1、Double类型

适用场景:双精度、非重要性、或“相对模糊”的数据存储。比如:百分比计算。

缺点:数值容易丢失精度。

优点:执行效率高。

2.2、BigDecimal类型

适用场景:较为严谨的数值计算。比如:交易金额相关计算。

优点:数值计算较为精准。

缺点:较Double类型执行效率弱一些。

三、为什么不建议用Double类型计算金额

3.1、Double类型计算精度易丢失

当我们进行数值加减乘除运算时,Double类型很大程度上会产生误差。

如下图示例,楼主定义了2个Double类型数据的加减乘除,运算结果有3个产生了误差。有误差,但是误差不大。

在这里插入图片描述

那么为什么会存在这个问题呢?

可想而知,double类型在运算时,会先将数值转换成二进制然后再做运算。但是在转换过程中,可能会发生存储小数部分的位数不够的现象(无限循环小数),所以很大程度上可能会有非常小的误差产生

因此,不要直接使用入参double类型数值直接进行运算。可考虑使用string类型参数进行处理。

在这里插入图片描述

3.2、数值过大会变为科学记数法形式

当数值过大时,会变为这种科学记数法形式。

在这里插入图片描述
解决方案:可考虑使用BigDecimal类型进行转换。

四、BigDecimal常用方法

4.1、BigDecimal的初始化

楼主分别定义了2个不同类型的入参。

在这里插入图片描述

眼尖的小伙伴估计注意到了,实例化a对象时new BigDecimal(“0.12”)传入的是字符串,实例化b对象时new BigDecimal(0.12)传入的是double数值。大家觉得运行结果会一样吗?

可能不一样吧…嗯,不是可能,是一定!!!

在这里插入图片描述

字符串类型的输出了“0.12”,而double数值类型的却输出了“0.11999999999999999555910790149937383830547332763671875”。

在这里插入图片描述

这又回归到了上面说所的二进制转换存储小数部分的位数不够,造成的误差。使用double类型初始化BigDecimal对象,进行运算时可能会出现精度不准确的问题。

在这里插入图片描述

所以一定注意:不要使用double类型作为入参,直接去new一个BigDecimal对象!可能会有精度误差!

那么,为什么string就可以呢?

string是不可变的,定义为string之后再转换为数值肯定是固定的啊。

底层很多实现也是这个原理。比如BigDecimal.valueOf()方法,如果输入的是double类型,实质上源码中还是先转化为了字符串。

在这里插入图片描述

对于整型或保留小数位的,也有相应的处理方法。

在这里插入图片描述

方法有很多,大家想了解的可自行研究下,楼主就不再一一示例啦。

在这里插入图片描述

4.2、BigDecimal加法

BigDecimal add(BigDecimal augend)

在这里插入图片描述

两个BigDecimal类型数据相加,方法调用、及运行效果。

在这里插入图片描述

4.3、BigDecimal减法

BigDecimal subtract(BigDecimal subtrahend)

在这里插入图片描述
两个BigDecimal类型数据相减,方法调用、及运行效果。

在这里插入图片描述

4.4、BigDecimal乘法

BigDecimal multiply(BigDecimal multiplicand)

在这里插入图片描述

两个BigDecimal类型数据相乘,方法调用、及运行效果。

在这里插入图片描述

4.5、BigDecimal除法

BigDecimal divide(BigDecimal divisor)

在这里插入图片描述

两个BigDecimal类型数据相除,方法调用、及运行效果。

在这里插入图片描述

哎呦,惊喜不惊喜,意外不意外?相除的时候出现了无限循环小数

因此 相除的场景下尽可能设置保留小数位,可避免运算当中抛出异常

在这里插入图片描述

4.6、BigDecimal比较大小

楼主分别定义了2个值为“0.12”的数据a、b,以及值为“0.120”的数据c进行比较。

在这里插入图片描述

可以发现:相同值“0.12”通过双等号对比返回的结果是false,equals对比返回的是true。而“0.12”和“0.120”实质上数值大小是一样的,但通过双等号或equals进行对比,返回均为false

那么,对于BigDecimal类型如何比较大小呢?(叫我靓妹我就告诉你…)

在这里插入图片描述

方法就是:使用compareTo方法进行比较

在这里插入图片描述

a、b两值进行比较:a.compareTo(b) 。 结果为0表示a、b值相等。结果为-1表示a小于b。结果为1表示a大于b

4.7、BigDecimal工具类

为大家附上常用的操作工具类,直接调用即可。


package com.wss.demo.cas;import java.math.BigDecimal;public class ArithUtil {private static final int DEF_DIV_SCALE = 2; // 小数点后的保留位数/*** Double精确的加法运算** @param d1 被加数* @param d2 加数* @return 两个参数的和*/public static BigDecimal add(double d1, double d2) {BigDecimal value1 = new BigDecimal(Double.toString(d1));BigDecimal value2 = new BigDecimal(Double.toString(d2));return value1.add(value2);}/*** Double精确的减法运算** @param d1 被减数* @param d2 减数* @return 两个参数的差*/public static BigDecimal sub(double d1, double d2) {BigDecimal value1 = new BigDecimal(Double.toString(d1));BigDecimal value2 = new BigDecimal(Double.toString(d2));return value1.subtract(value2);}/*** Double精确的乘法运算** @param d1 被乘数* @param d2 乘数* @return 两个参数的积*/public static BigDecimal mul(double d1, double d2) {BigDecimal value1 = new BigDecimal(Double.toString(d1));BigDecimal value2 = new BigDecimal(Double.toString(d2));return value1.multiply(value2);}/*** Double精确的除法运算, 当出现除不尽的情况时, 精确到小数点以后n位, 以后的数字四舍五入** @param d1 被除数* @param d2 除数* @return 两个参数的商*/public static BigDecimal div(double d1, double d2) {return div(d1, d2, DEF_DIV_SCALE);}/*** Double精确的除法运算, 当出现除不尽的情况时, 精确到小数点以后n位, 以后的数字四舍五入** @param d1    被除数* @param d2    除数* @param scale 表示需要精确到小数点的后几位* @return 两个参数的商*/public static BigDecimal div(double d1, double d2, int scale) {if (scale < 0) {throw new IllegalArgumentException("参数[scale]必须是正整数或者零");}BigDecimal value1 = new BigDecimal(Double.toString(d1));BigDecimal value2 = new BigDecimal(Double.toString(d2));return value1.divide(value2, scale, BigDecimal.ROUND_HALF_UP);}/*** 比较大小*/public static boolean equalTo(BigDecimal b1, BigDecimal b2) {if(b1 == null || b2 == null) {return false;}return 0 == b1.compareTo(b2);}}

嗯,今天的总结就先到这吧。散会了,别忘记给三婶儿点个赞哈~

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java面试 - 多线程并发篇

多线程&并发篇 chatGPT以及GPT-4免费体验&#xff01; java面试 - 基础篇 java面试-JVM篇 java面试-spring篇 &#xff08;持续更新中&#xff09; java面试-MyBatis篇 &#xff08;持续更新中&#xff09; java面试-springBoot篇 &#xff08;持续更新中&#xff09; ja…

5分钟!使用ChatGPT读懂一本书;写给独立开发者的设计指南;麦肯锡报告:生成式AI的经济潜力;GitHub报告:AI对开发影响深远 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 时代杂志「2023年100家最具影响力企业」 时代杂志发布了「TIME100 MOST INFLUENTIAL COMPANIES 2023」&#xff0c;评选出2023年最具影…

自然语言成了编程语言,不会写 Prompt 的程序员会面临失业吗?

作者 | 王启隆 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 如果让一个活在 18 世纪的人看看今天的世界&#xff0c;他会被现代科技的伟大所震慑&#xff0c;沉醉于未来社会的梦幻&#xff1b;但如果让一个 15 世纪的人去看看 18 世纪的世界&#xff0c;就感受…

文案策划将会被ChatGPT淘汰么?道叔用了两月后,惊呆了!

用了ChatGPT一段时间了&#xff0c;发现这真的是一个非常好用的划时代的产品。 我们文案策划人如果用熟练了的话&#xff0c;能够节省大量时间。未来&#xff0c;各行各业的脑力劳动者真的都不需要现在这么多了。 如果说&#xff0c;未来机器人将把大量工人淘汰的话&#xff…

一文看懂GPT风口,都有哪些创业机会?

新时代的淘金者&#xff0c;低附加价值的创业要谨慎&#xff0c;高附加价值、低技术门槛创业也要谨慎&#xff0c;主干道边上的创业也要谨慎。不少朋友看完不淡定了&#xff0c;干什么都谨慎&#xff0c;回家躺平好了&#xff0c;我有个朋友&#xff0c;靠ChatGPT&#xff0c;半…

虚拟邮箱地址-可随意接收邮箱验证码——网站

唠下互联网环境的嗑&#xff1a;国内的互联网环境在注册账号这一方面是真的不尊重个人隐私&#xff0c;只有手机号码注册的选项。vanker留意到海外的网址基本都是邮箱即可注册账号&#xff0c;希望国家能够制定详细的相应标准。所以提醒大家&#xff1a;在一般的网站上不要轻易…

ChatGPT 真的太强大了!

如果你问我&#xff0c;2023年最大的机会是什么&#xff1f;那一定是——ChatGPT 从2月份GPT3.5版本发布&#xff0c;到现在的4.0PLUS升级版&#xff0c;ChatGPT的迭代速度已经完全超过了我们的想象。 它已经可以替代很多行业的工作&#xff08;比如说&#xff1a;文案、程序、…

chatGpt AI智能模拟面试系统开发

在当今竞争激烈的就业市场&#xff0c;求职者不仅需要具备扎实的专业知识和技能&#xff0c;还需要通过面试展现出自己的优势。 chatGpt AI智能模拟面试系统利用了人工智能技术&#xff0c;以及OpenAI的强大语言模型ChatGpt为基础。旨在为求职者提供一个真实且个性化的面试体验…

张俊林:由ChatGPT反思大语言模型(LLM)的技术精要

原文&#xff1a;张俊林&#xff1a;由ChatGPT反思大语言模型&#xff08;LLM&#xff09;的技术精要 张俊林 人机与认知实验室 2023-02-15 00:00 发表于北京 实话实说&#xff0c;国内在LLM模型相关技术方面&#xff0c;此刻&#xff0c;距离最先进技术的差距进一步加大了。…

提示工程师指南3-Prompt工程-高级提示

高阶Prompting 到这一步&#xff0c;应该很明显&#xff0c;改进提示有助于在不同任务上获得更好的结果。这就是Prompt工程背后的整个理念。 虽然之前的例子很有趣&#xff0c;但在我们深入了解更高级的概念之前&#xff0c;让我们先正式地介绍一些概念。 文章目录 高阶Promp…

Interview: Kevin Kelly, editor, author, and futurist采访:凯文·凯利,编辑、作家、未来学家

By Cmichel67 - Own work, CC BY-SA 4.0 作者&#xff1a;Cmichel 67-自己的作品&#xff0c;CC BY-SA 4. 0 Kevin Kelly is one of the thinkers who helped define the ethos of the tech industry from its early days. As an editor of the Whole Earth Catalog in the 198…

文心一言云服务下周上线/ 亚马逊再裁9000人/ 首款GPT-4医用软件问世…今日更多新鲜事在此...

日报君 发自 凹非寺量子位 | 公众号 QbitAI 大噶好&#xff0c;今天是3月21日星期二&#xff0c;打工人&#xff0c;勇敢冲(:з」∠) 科技圈又发生了哪些新鲜事&#xff0c;一起来和日报君看看&#xff5e; 亚马逊再裁员9000人 北京时间3月20日晚间&#xff0c;亚马逊宣布将再裁…

【调研】生成式PLM模型(偏LLM)压缩

研究背景 常用的生成模型 下表总结了现在常用的生成模型的架构、参数量、尺寸和开源地址。其中参数量基本为亿万级别&#xff0c;以decoder的架构为主&#xff0c;模型尺寸在500MB以上。 模型名称架构尺寸层数参数量(Billion)开源地址备注GPT-2decoder548 MB481.5Bhttps://h…

哈哥的博客阅读指南,一文对接全链路导引 --- 未完待续~

文章目录 ⭐️ 一、关于 "易编程社区"&#x1f31f; 社区及星球诞生的初衷&#x1f31f; 加入社区和星球可以收获什么&#xff1f;&#x1f31f; 来自哈哥的公开承诺&#x1f31f; 哈哥的简介 ⭐️ 二、星荐官计划奖金池⭐️ 三、专栏解读&#x1f31f; 专栏 - 编程初…

一句话让ChatGPT 支持图片回复!

ChatGPT 很智能&#xff0c;很聪明。但是它被困在了互联网里&#xff0c;只能通过网页上的文字&#xff0c;和我们交流。 就像历史上的一个个有趣的灵魂&#xff0c;我们只能通过书中的文字和故事&#xff0c;才能领会到他们的千古风流。 纯文字的方式&#xff0c;还是太单调…

outlook 回复邮件的邮件头使用RE而不是回复

在outlook的"工具" -> "选项" &#xff1a; 点击 “选项" -> "邮件格式" -> "国际选项" : 这里勾选上“常规设置”的选项即可。

科大讯飞版ChatGPT开放内测(文末附内测地址,亲测一秒通过审核)

本周讯飞骤然向开发者提供了内测通道&#xff0c;取名为讯飞星火认知大模型&#xff08;以下亲切地叫它阿讯&#xff09;对外开启内测。 国内大模型关注度陡增后&#xff0c;科大讯飞率先给出了deadline&#xff1a;5月6日上线产品。没想到&#xff0c;他们毫无征兆地开启了内…

体验讯飞星火认知大模型,据说中文能力超越ChatGPT

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

超越ChatGPT?新发布:“讯飞星火认知大模”到底行不行?

国内又一巨头发布 大语言模型&#xff0c;是 PPT 融资还是真材实料 &#xff1f; 作为程序员&#xff0c;到底面对这一趋势&#xff0c;我们何去何从 &#xff1f; 目录 讯飞星火&#xff0c;5月6日如约而至 一、你真的了解科大讯飞吗&#xff1f; 二、讯飞星火大模型将超越…

科大讯飞版ChatGPT开始内测《讯飞星火》

科大讯飞版ChatGPT产品&#xff0c;提前交卷了&#xff01; 就在昨夜&#xff0c;讯飞骤然向开发者提供了内测通道&#xff0c;取名为讯飞星火认知大模型对外开启内测。 还有个神奇的英文名字Spark Desk&#xff0c;据说有“火花桌面智能助手”的意思。 申请的过程很简单。用…