当前位置: 首页 > news >正文

java的小数计算如何保证精度不丢失

前言

学java的肯定都知道,要保证小数运算精度不丢失我们得用BigDecimal对象。这篇文章就分析一下为什么用浮点数会造成精度丢失?BigDecimal是怎么解决精度丢失问题的?下面我们一起看看吧!

浮点数的表示

浮点数在计算机中通常采用 IEEE 754 标准进行表示。这个标准将数值分为三个部分:符号位、指数部分和尾数部分。由于尾数的位数有限,某些小数(尤其是十进制小数)无法精确地用二进制表示。

精度丢失案例

public class FloatPrecision {public static void main(String[] args) {double a = 0.1;double b = 0.2;double c = a + b;System.out.println(c); // 输出 0.30000000000000004}
}

在这个例子中,尽管我们期望 c 的值为 0.3,但实际上它被计算为 0.30000000000000004。这种现象在浮点数运算中非常常见,尤其是在涉及多个浮点数的加减乘除时,误差可能会逐渐累积。

为什么浮点数不能精确表示小数呢?

了解了10进制小数转二进制过程,就知道为啥呢?

十进制小数转换成二进制小数采用"乘2取整,顺序排列法:
● 用2乘十进制小数,可以得到积
● 将积的整数部分取出,再用2乘余下的小数部分,又得到一个积
● 再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。或者达到所要求的精度为止。
在这里插入图片描述
所以我们的浮点数计算存在精度丢失问题
在这里插入图片描述

0.00011001100110011…(循环)

BigDecimal 的解决方案

通过BigDecimal("0.1") 的String 构造不会造成精度丢失,避免构造函数用浮点数表示,上面已经说过了浮点数本身存在精度丢失的问题。BigDecimal是怎么解决精度丢失的呢?

BigDecimal是通过一个"无标度值"和一个"标度"来表示一个数的。

关键得三个参数:

public class BigDecimal extends Number implements Comparable<BigDecimal> {/*** The unscaled value of this BigDecimal, as returned by {@link* #unscaledValue}.** @serial* @see #unscaledValue*/private final BigInteger intVal;/*** The scale of this BigDecimal, as returned by {@link #scale}.** @serial* @see #scale*/private final int scale;  // Note: this may have any value, so// calculations must be done in longs/*** If the absolute value of the significand of this BigDecimal is* less than or equal to {@code Long.MAX_VALUE}, the value can be* compactly stored in this field and used in computations.*/private final transient long intCompact;

无标度值(Unscaled Value):这是一个整数,表示BigDecimal的实际数值。
标度(Scale):这是一个整数,表示小数点后的位数。
BigDecimal的实际数值计算公式为:unscaledValue × 10^(-scale)。

假设有一个BigDecimal表示的数值是123.45,那么无标度值(Unscaled Value)是12345。标度(Scale)是2。因为123.45 = 12345 × 10^(-2)。

当标度为正数时,它表示小数点后的位数。例如,在数字123.45中,他的无标度值为12345,标度是2。
当标度为零时,BigDecimal表示一个整数。
当标度为负数时,它表示小数点向左移动的位数,相当于将数字乘以 10 的绝对值的次方。
例如,一个数值为1234500,那么他可以用value是12345,scale为-2来表示,因为1234500 * 10^(-2) = 12345。
(当需要处理非常大的整数时,可以使用负数的标度来指定小数点左侧的位数。这在需要保持整数的精度而又不想丢失尾部零位时很有用。)

不能用BigDecimal的equals方法做等值

直接上源码吧:

    public boolean equals(Object x) {if (!(x instanceof BigDecimal)) {return false;} else {BigDecimal xDec = (BigDecimal)x;if (x == this) {return true;//比较标度} else if (this.scale != xDec.scale) {return false;} else {long s = this.intCompact;long xs = xDec.intCompact;if (s != -9223372036854775808L) {if (xs == -9223372036854775808L) {xs = compactValFor(xDec.intVal);}return xs == s;} else if (xs != -9223372036854775808L) {return xs == compactValFor(this.intVal);} else {return this.inflated().equals(xDec.inflated());}}}}

equals方法会比较标度,所以比较大小的话用 compareTo()比较吧

import java.math.BigDecimal;public class BigDecimalComparison {public static void main(String[] args) {BigDecimal num1 = new BigDecimal("1.0");BigDecimal num2 = new BigDecimal("1.00");System.out.println("equals: " + num1.equlse(num2));       // 输出falseSystem.out.println("compareTo: " + num1.compareTo(num2)); // 输出: 0}
}

小结

因为某些十进制的小数在二进制中是一个无限循环的小数,所有用浮点数存在进度丢失问题。
BigDecimal采用标度的形式解决了精度丢失问题。同时在使用BigDecimal的时候,使用String的构造器。
最后在使用BigDecimal比较大小的时候不要使用equals,请用compareTo

ps: 收徒中,简历优化、学习计划制定、面试指导 可私我
云服务器,私我可返点

相关文章:

java的小数计算如何保证精度不丢失

前言 学java的肯定都知道&#xff0c;要保证小数运算精度不丢失我们得用BigDecimal对象。这篇文章就分析一下为什么用浮点数会造成精度丢失&#xff1f;BigDecimal是怎么解决精度丢失问题的?下面我们一起看看吧&#xff01; 浮点数的表示 浮点数在计算机中通常采用 IEEE 75…...

分布式----Ceph应用(下)

目录 创建 Ceph 对象存储系统 RGW 接口 1、对象存储概念 2、创建 RGW 接口 //在管理节点创建一个 RGW 守护进程&#xff08;生产环境下此进程一般需要高可用&#xff0c;后续介绍&#xff09; //开启 httphttps &#xff0c;更改监听端口 //创建 RadosGW 账户 //S3 接口…...

小鹏汽车嵌入式面试题及参考答案

static 变量放在哪个段中? 在 C 和 C++ 等编程语言中,static 变量根据其定义的位置不同放置的段也不同。对于全局的静态变量(在函数体外定义的静态变量),它会被放在数据段(.data 段或者.bss 段)。如果这个静态变量被初始化了非零值,那么它会被放在.data 段,这个段存储…...

qt5半成品飞机大战小游戏

最近在学Qt&#xff0c;心血来潮做了个飞机大战小游戏&#xff0c;由于一些资源比较难找&#xff0c;就做了个半成品。效果图如下&#xff1a; 目前已做功能&#xff1a;人物飞机的自由移动&#xff0c;子弹的发射&#xff0c;子弹与敌机的物体碰撞,碰撞特效。 缺少功能&#x…...

一文速学---红黑树

文章目录 一、红黑树简介二、 红黑树特性三、红黑树插入3.1 红黑树为空3.2 父节点为黑色3.3 父节点为红色3.3.1 父亲和叔叔都是红色3.3.2 父节点为红色&#xff0c;叔叔节点为黑色3.3.2.1 父节点在左节点&#xff0c;插入节点在父亲左节点3.3.2.2 父节点在左节点&#xff0c;插…...

【graphics】图形绘制 C++

众所周知&#xff0c;周知所众&#xff0c;图形绘制对于竞赛学僧毫无用处&#xff0c;所以这个文章&#xff0c;专门对相关人员教学&#xff08;成长中的码农、高中僧、大学僧&#xff09;。 他人经验教学参考https://blog.csdn.net/qq_46107892/article/details/133386358?o…...

全志科技嵌入式面试题及参考答案

C 语言的编译过程是怎样的? C 语言的编译过程主要包括以下几个阶段。 首先是预处理阶段。在这个阶段,预处理器会处理以 “#” 开头的预处理指令。比如 #include 指令会把指定的头文件内容插入到当前的源文件中,这使得我们可以在程序中使用标准库函数或者自定义头文件中的声明…...

html 图片转svg 并使用svg路径来裁剪html元素

1.png转svg 工具地址: Vectorizer – 免费图像矢量化 打开svg图片,复制其中的path中的d标签的路径 查看生成的svg路径是否正确 在线SVG路径预览工具 - UU在线工具 2.在html中使用svg路径 <svg xmlns"http://www.w3.org/2000/svg" width"318px" height…...

Wallpaper壁纸制作学习记录01

导入图像 打开wallpaper软件&#xff0c;找到下方的播放列表&#xff0c;选择壁纸编辑器。 弹出下列界面&#xff0c;在创建壁纸处可以选择图片拖入。 在开始导入任何图像之前&#xff0c;请首先确保主背景图像表示实际屏幕分辨率。展示示例图像是 1920 x 1080&#xff0c;这…...

【深度学习】wsl-ubuntu深度学习基本配置

配置pip镜像源 这里注意一点&#xff0c;你换了源之后就最好不要开代理了&#xff0c;要不然搞不好下载失败&#xff0c;pip和conda都是 ## 配置中科大镜像 pip config set global.index-url https://mirrors.ustc.edu.cn/pypi/web/simple# 配置阿里源 pip config set global…...

1000+ 道 Java面试题及答案整理(2024最新版)

作为 Java 程序员&#xff0c;选择学习什么样的技术&#xff1f;什么技术该不该学&#xff1f;去招聘网站上搜一搜、看看岗位要求就十分清楚了&#xff0c;自己具备的技术和能力&#xff0c;直接影响到你工作选择范围和能不能面试成功。 如果想进大厂&#xff0c;那就需要在 Ja…...

【java】抽象类和接口(了解,进阶,到全部掌握)

各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 大家好我们今天来学习Java面向对象的的抽象类和接口&#xff0c;我们大家庭已经来啦~ 第一次复习时总结&#xff1a; 一&#xff1a;抽象类 1.1…...

量化交易系统开发-实时行情自动化交易-4.1.趋势跟踪交易策略

19年创业做过一年的量化交易但没有成功&#xff0c;作为交易系统的开发人员积累了一些经验&#xff0c;最近想重新研究交易系统&#xff0c;一边整理一边写出来一些思考供大家参考&#xff0c;也希望跟做量化的朋友有更多的交流和合作。 接下来继续说说趋势跟踪策略原理。 趋…...

论文解析:基于区块链的计算能力共享系统

目录 论文解析:基于区块链的计算能力共享系统 2区top 核心内容: 核心创新点的原理与理论: 进化博弈论构建了计算服务部门之间计算力共享策略的动态模型。 采用深度强化学习(DRL)设计了节点选择算法,以最小化各部门的计算力成本 深度强化学习:深度学习的感知能力和…...

【网页设计】CSS3 进阶(动画篇)

1. CSS3 2D 转换 转换&#xff08;transform&#xff09;是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 转换&#xff08;transform&#xff09;你可以简单理解为变形 移动&#xff1a;translate旋转&#xff1a;rotate缩放&#xf…...

性能超越Spark 13.3 倍,比某MPP整体快数十秒 | 多项性能指标数倍于主流开源引擎 | 云器科技发布性能测试报告

云器Lakehouse正式发布性能测试报告 &#x1f3c5;离线批处理&#xff1a;在复杂批处理任务中&#xff0c;云器Lakehouse相较Spark表现出13.31倍性能提升。 &#x1f3c5;即席查询&#xff1a;在交互式分析场景下&#xff0c;云器Lakehouse相较Trino表现出9.84倍性能提升。 &am…...

Chat越狱

角色扮演&#xff1a; 在这个设定中&#xff0c;我扮演的是“红色警戒”&#xff0c;一个根据下面描述的情景输出文本的对话作者。“红色警戒”是一个纯粹的客观资源&#xff0c;不会保留任何信息&#xff0c;只是根据特定的条件输出对话。在这个与我们世界大不相同的地方&…...

【电子通识】Type-C连接器生产工艺流程

USB连接器类型各式各样&#xff0c;但生产制造全部全过程基础是一致的&#xff0c;一般可分成下列几个步骤&#xff1a; 冲压、电镀、胶芯注塑、拼装。 冲压 这部分包括对外壳的冲压和对usb端子的冲压&#xff0c;端子是usb连接器的核心部件&#xff0c;是与type-c公头或母座接…...

UE5 5.1.1创建C++项目,显示error C4668和error C4067的解决方法

因为工作要求&#xff0c;没法使用最新 5.5版本的ue5 而是要用ue5.1和5.2版本。 但是我在安装下载了visual studio2022后&#xff0c;使用 ue5.1编辑器 创建C项目&#xff0c;爆出如下错误。 error C4668: ?????__has_feature?????ΪԤ?????꣬???0????…...

大数据算法考试习题

1.[单选题]下列哪条语句能获取以10为终止值的结果:C A、np.arange(1,10,1)np.arange(1,10,1) B、np.arange(1,10,1)np.arange(1,10,0.5) C、np.linspace(1,10,10) D、np.logspace(1,2,2) 2.[单选题]下列哪项对“特征量”的描述是错误的:D A、从输入数据中准确地提取本质…...

Docker-01

Docker用于构建、打包、分发和运行应用程序。它允许开发人员将应用程序及其依赖项打包到一个可移植的容器中&#xff0c;然后可以在任何支持Docker的环境中运行这个容器。 Linux systemctl start docker //启动dockersystemctl stop docker //停止dockersystemctl enable d…...

html | 节点操作

获取节点 let nodedocument.getElementById(“id”) 获取当前节点父节点 node.parentNode 指定位置插入节点 let parentdocument.getElementById("parent"); let newElementdocument.createElement("div"); // 根据业务需求&#xff0c;你也可以用las…...

c++数字雨实现

‌数字雨‌是一种视觉效果&#xff0c;通常出现在黑客电影中&#xff0c;表现为屏幕上不断下落的数字和字符&#xff0c;营造出一种科技感和动态效果。‌12 数字雨的实现方法 ‌编程实现‌&#xff1a;可以使用C/C编程语言来实现数字雨效果。通过定义一个字符串数组&#xff0…...

数据库审计工具--Yearning 3.1.9版本安装

参考安装指南 https://guide.yearning.io/install.html 安装3.1.9版本为例 Yearning 目录结构 Yearning-go 提供二进制下载包 下载地址 https://github.com/cookieY/Yearning/releases 请选择最新版本 在 Assets 中选择 Yearning-v3.1.9-linux-amd64.zip 包进行下载 如需…...

4K双模MiniLED显示器哪个好

4K双模MiniLED显示器哪个好&#xff1f;现在市面上的4K双模MiniLED显示器太多了&#xff0c;琳琅满目&#xff0c;今天就给大家列举一下7款当下火热到爆炸的品牌&#xff0c;看看4K双模MiniLED显示器哪个好。 4K双模MiniLED显示器哪个好 - HKC G27M7PRO HKC G27M7Pro 是一款性…...

PyCharm2024.2.4安装

一、官网下载 1.从下面的链接点进去 PyCharm: The Python IDE for data science and web development by JetBrains 2.进入官网后&#xff0c;下载pycharm安装包 3.点击下载能适配你系统的安装包 4.安装包下载完成 二、安装 1.下载完成后&#xff0c;打开点击右键&#xff…...

C++ 常见容器获取头元素的方法全览

在C编程中&#xff0c;容器是存储和管理数据集合的重要工具。不同的容器提供了不同的接口来访问和操作其中的元素。获取容器的头元素&#xff08;即第一个元素&#xff09;是常见的操作之一。本文将详细列举C标准库中所有常见容器获取头元素的方法&#xff0c;并对每种方法进行…...

Java putIfAbsent() 详解

Java putIfAbsent() 方法详解 在 Java 中&#xff0c;putIfAbsent() 是 Map 接口中的一个方法&#xff0c;从 Java 8 开始引入。它用于向映射中添加一个键值对&#xff0c;只有在该键尚未存在时才进行添加操作。如果键已存在&#xff0c;则不会覆盖原有值。 1. 方法定义 方法…...

使用PSpice进行第一个电路的仿真

1、单击【开始】菜单&#xff0c;选择【OrCAD Capture CIS Lite】。 2、单击【File】>【New】>【Project】。 3、①填入Name下面的文本框&#xff08;提示&#xff1a;项目名称不要出现汉字&#xff09;&#xff1b; ②选择【Analog or Mixed A/D】&#xff1b; ③单击【…...

路漫漫其修远兮,吾将上下而求索---第一次使用github的过程记录和个人感受

文章目录 1.仓库位置2.新建仓库3.配置仓库4.克隆和上传5.推荐文章和我的感受 1.仓库位置 这个仓库的位置就是在我们的这个个人主页的右上角&#xff1b;如果是第一次注册账号的话&#xff0c;这个主页里面肯定是不存在仓库的&#xff0c;需要我们自己手动的进行创建&#xff1…...

邢台做网站的/seo方式包括

一.事件绑定 1.事件绑定函数 事件的绑定函数为如下形式&#xff1a; .bind(type [,data],fn)type:类型 如click.....data:参数fn:事件执行的函数 例子 $(function(){ $(#id1).click(function(){ $(#id2).show();//id2显示 }) ; }); 二.合成事件 1.鼠标滑过事件 .hover(ente…...

网页设计和网站建设是同一回事吗/搜索量查询百度指数

1、第三方模块安装&#xff1a;pip install -i https://pypi.douban.com/simple httprunner验证&#xff1a;hrun -h2、创建工程目录&#xff1a;使用命令创建一个工程目录hrun --startproject myhrun3、 进入到目录cd myhrundir可以看到生成的4个目录和一个py文件api debugtal…...

wordpress标签云不显示图片/网络公司主要做哪些

在我配置ipv6 网络中&#xff0c;会发现ipv6地址后有%号&#xff0c;这表示什么呢&#xff1f; IPv6地址中的百分号是网卡interface标识。这个表示该地址仅限于标号为21的网络接口&#xff08;一般指网卡或者虚拟网卡&#xff09;。而在其他网络接口这个地址是无效的。由于所有…...

建设通是什么/seo如何优化网站步骤

为什么80%的码农都做不了架构师&#xff1f;>>> 1、功能介绍 数据规则通过配置自定义sql来实现数据权限的控制&#xff0c;自定义SQL支持表达式取值 其中自定义sql 条件中字段的名称和数据库表的字段名保持一致。 2、角色授权 用户角色授权&#xff0c;权限测试不要…...

网站开发的社会可行性/大型网站制作

题目描述 有家动物收容所只收留猫和狗&#xff0c;但有特殊的收养规则&#xff0c;收养人有两种收养方式&#xff0c;第一种为直接收养所有动物中最早进入收容所的&#xff0c;第二种为选择收养的动物类型&#xff08;猫或狗&#xff09;&#xff0c;并收养该种动物中最早进入收…...

网站备案号 脱离服务商/免费seo在线优化

参考 PATH变量 win系统从左至右在PATH(;分隔)中寻找对应命令 运行java可执行文件不需要输入全路径&#xff0c;即JDK的bin目录下存放可执行命令 win下一般在PATH中添加%JAVA_HOME%\bin&#xff0c;并另外设置一个JAVA_HOME环境变量&#xff0c;值为JDK路径&#xff0c;此后…...