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

double类型 精度丢失的问题

前言

精度丢失的问题是在其他计算机语言中也都会出现,float和double类型的数据在执行二进制浮点运算的时候,并没有提供完全精确的结果。产生误差不在于数的大小,而是因为数的精度。

一、double进行运算时,经常出现精度丢失

0.1+0.2使用计算器计算是0.3,代码里却是0.30000000000000004

二、使用Java代码运行

 为什么会这样呢?这就是精度丢失问题造成的。

因为计算机只能识别0和1,即二进制,无论哪种编程语言,都需要翻译成二进制才能被计算机识别。这种舍入误差的主要原因是浮点数值采用二进制系统表示, 而在二进制系统中无法精确地表示分数 1/10。这就好像十进制无法精确地表示分数 1/3—样。

针对十进制,1除以3是除不尽的。很好理解,因为我们一直接触的就是十进制,等于0.333333… 但是,二进制系统中无法精确地表示分数 1/10。

我们看下面的示例代码:

十进制转二进制(每次将小数部分乘2,取出整数部分,如果小数部分为0,就可以停止这个过程):十进制0.1计算如下:

public class Test5 {public static void main(String[] args) {//十进制 转二进制double a = 0.1 * 2;//0.2double b = 0.2 * 2;//0.4double c = 0.4 * 2;//0.8double d = 0.8 * 2;//1.6double e = 0.6 * 2;//1.2double f = 0.2 * 2;//0.4double g = 0.4 * 2;//0.8double h = 0.8 * 2;//1.6System.out.println(a+","+b+","+c+","+d);System.out.println(e+","+f+","+g+","+h);//我们发现,上面的过程已经开始循环,小数部分永远不能为0}
}

当某个业务场景对double数据的精度要求非常高时,就必须采取某种手段来处理这个问题,这也是BigDecimal为什么会被广泛应用于金额支付场景中的原因。

BigDecimal类位于java.math包下,用于对超过16位有效位的数进行精确的运算。一般来说,double类型的变量可以处理16位有效数,但实际应用中,如果超过16位,就需要BigDecimal类来操作。

三、BigDecimal类常用的有参构造器

new BigDecimal(String val)

    /* @param val String representation of {@code BigDecimal}.** @throws NumberFormatException if {@code val} is not a valid*         representation of a {@code BigDecimal}.*/public BigDecimal(String val) {this(val.toCharArray(), 0, val.length());}

new BigDecimal(double val) 

/* @param val {@code double} value to be converted to*        {@code BigDecimal}.* @throws NumberFormatException if {@code val} is infinite or NaN.*/public BigDecimal(double val) {this(val,MathContext.UNLIMITED);}

BigDecimal.valueOf(double val) 

    /* @param  val {@code double} to convert to a {@code BigDecimal}.* @return a {@code BigDecimal} whose value is equal to or approximately*         equal to the value of {@code val}.* @throws NumberFormatException if {@code val} is infinite or NaN.* @since  1.5*/public static BigDecimal valueOf(double val) {// Reminder: a zero double returns '0.0', so we cannot fastpath// to use the constant ZERO.  This might be important enough to// justify a factory approach, a cache, or a few private// constants, later.return new BigDecimal(Double.toString(val));}

四、将double转为BigDecimal的时候,需要先把double转换为字符串,然后再作为BigDecimal(String val)构造函数的参数,这样才能避免出现精度问题。

        double d1 = 0.1;double d2 = 0.2;double d3 = d1 + d2; //可能精度丢失问题double d4 = d1 * d2; //可能精度丢失问题System.out.println("d1 + d2 = "+d3);System.out.println("d1 * d2 = "+d4);/*** BigDecimal类位于java.math包下,用于对超过16位有效位的数进行精确的运算。* 一般来说,double类型的变量可以处理16位有效数,* 但实际应用中,如果超过16位,就需要BigDecimal类来操作*/BigDecimal bigDecimal = BigDecimal.valueOf(d1);//也可以使用BigDecimal p1 = new BigDecimal(Double.toString(d1));//推荐使用BigDecimal p2 = new BigDecimal(Double.toString(d2));
//        BigDecimal add = p1.add(p2);double v = p1.add(p2).doubleValue();double v1 = p1.multiply(p2).doubleValue();System.out.println("-------"+v);//0.3System.out.println("-------"+v1);//0.02

总结如下:

Java中的double类型确实存在精度丢失的问题,‌这主要源于其内部表示和运算规则。‌以下是导致double类型精度丢失的主要原因:‌

  1. 范围限制:‌double类型有其能表示的最大和最小值范围。‌当数值超出这个范围时,‌转换会导致精度丢失或发生溢出。‌
  2. 小数位数限制:‌double类型有限的位数可能无法完全表示非常长的小数部分,‌导致舍入错误或精度丢失。‌
  3. 十进制数的表示问题:‌由于double是基于二进制的浮点数表示,‌某些十进制数可能无法准确表示,‌这也会导致精度丢失。‌例如,‌0.1这个十进制数在二进制浮点表示中是一个无限循环小数,‌转换为double类型时会有精度损失。‌
  4. 运算过程中的精度丢失:‌在进行算术运算时,‌如果参与运算的数的精度高于double类型的精度,‌则运算过程中可能会出现舍入错误,‌导致最终结果的精度丢失。‌

为了避免这些问题,‌特别是在金融或需要高精度计算的领域,‌建议使用BigDecimal类进行精确运算。‌BigDecimal类位于java.math包下,‌用于对超过16位有效位的数进行精确的运算。‌将double转换为BigDecimal时,‌需要先把double转换为字符串,‌然后再作为BigDecimal构造函数的参数,‌这样可以避免出现精度问题。‌此外,‌连续的浮点数运算会累积精度误差,‌因此在进行大量计算或对精度有严格要求的情况下,‌使用BigDecimal类进行计算是更为合适的选择。

相关文章:

double类型 精度丢失的问题

前言 精度丢失的问题是在其他计算机语言中也都会出现,float和double类型的数据在执行二进制浮点运算的时候,并没有提供完全精确的结果。产生误差不在于数的大小,而是因为数的精度。 一、double进行运算时,经常出现精度丢失 0.10.2使用计算…...

C++ 重要特性探究

shared_from_this 使用分析 场景 类的成员函数需要获取指向自身的shared_ptr的时候类成员函数传递shared_ptr给其他函数或者对象的时候&#xff0c;目的是为了管理对象生命周期使用方法 首先类必须继承 std::enable_shared_from_this<T>必须使用 shared_from_this 获取指…...

c++_游戏_狼人杀

思路主要包括以下几个部分&#xff1a; 角色分配&#xff1a;代码中通过随机数的方式给狼人、平民、预言家和法师等角色进行分配&#xff0c;保证每个角色的数量和身份的随机性。 游戏进行&#xff1a;根据狼人、平民、预言家和法师等角色的身份&#xff0c;游戏进行了夜晚和白…...

MySQL——数据类型、索引的建立、数据的约束

文章目录 数据类型索引的建立普通索引唯一索引使用ALTER 命令添加和删除索引使用ALTER 命令添加和删除主键显示索引信息 数据的约束非空约束&#xff1a;not null&#xff0c;值不能为null唯一约束&#xff1a;unique&#xff0c;值不能重复主键约束&#xff1a;primary key外键…...

常见框架漏洞详解③!!

Apache Apache 是世界使⽤排名第⼀的 Web 服务器软件。它可以运⾏在⼏乎所有⼴泛使⽤的计算 机平台上&#xff0c;由于其跨平台和安全性被⼴泛使⽤&#xff0c;是最流⾏的 Web 服务器端软件之⼀。 apache⽬录结构&#xff1a; bin&#xff1a;存放常⽤命令⼯具&#xff0c;如h…...

大数据基础知识

大数据&#xff08;Big Data&#xff09;是指无法用传统数据处理工具和技术有效处理的大规模、复杂的数据集。大数据技术通过对这些数据进行存储、处理和分析&#xff0c;从中提取有价值的信息和见解。 1. 大数据的特点 大数据通常具有以下四个主要特点&#xff0c;被称为“4…...

SQL Server 的透明数据加密

透明数据加密是SQL Server数据库安全众多特性中的一个&#xff0c;本文只针对透明数据加密。 在此测试之前&#xff0c;已经按照文档如何快速获得一个测试用SQL Server企业版创建了一个SQL Server 2019&#xff0c;并按照文档为SQL Server安装示例数据库AdventureWorks安装了…...

Windows图形界面(GUI)-MFC-C/C++ - 列表视图(List Control) - CListCtrl

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 列表视图(List Control) - CListCtrl 创建列表视图 设置列表视图属性 成员函数 注意事项 示例代码 列表视图(List Control) - CListCtrl 创建列表视图 在对话框编辑器中&#xff…...

一机两用的简单介绍

电子政务外网终端使用过程的风险与挑战 1、终端防护弱&#xff0c;失陷风险大 政务外网终端具备访问互联网能力&#xff0c;造成政务外网终端极易感染僵木蠕病毒&#xff0c;破坏正常办公 政务外网终端易被攻击失陷&#xff0c;成为从互联网攻击政务外网的跳板机 2、VPN漏洞…...

uniapp离线打包热更新失败-AndroidStudio离线打包apk后无法下载打开-热更新失败-plus.runtime.install失败

效果图 仅安卓 前言 1.plus.runtime.install一直fail(20240808), uni.openDocument可以打开本地apk文件 2.权限问题需小心 跑通前提 1.先确定apk地址有效&#xff0c;浏览器中手动下载可安装 2.确保已添加离线打包AndroidStudio的“android.permission.INSTALL_PACKAGES”权…...

深植根基、蓬勃向上 | openKylin 2.0正式发布!

2024年8月8日&#xff0c;openKylin 2.0版本正式发布&#xff01;该版本默认搭载Linux 6.6 LTS内核&#xff0c;完成180操作系统核心组件自主选型升级&#xff0c;深度融合AI技术&#xff0c;上线麒麟AI助手等实用AI功能&#xff0c;并为用户带来包括开明软件包格式、不可变系统…...

【Material-UI】按钮组:尺寸与颜色详解

文章目录 一、按钮组概述1. 组件介绍2. 基本用法 二、按钮组的尺寸&#xff08;Sizes&#xff09;1. 小尺寸&#xff08;Small&#xff09;2. 中等尺寸&#xff08;Medium&#xff09;3. 大尺寸&#xff08;Large&#xff09; 三、按钮组的颜色&#xff08;Colors&#xff09;1…...

app抓包 burp配置

证书导出 模拟器安装证书 点击安装证书 将证书直接拖进来就行 配置代理 打开浏览器抓包...

图像与像素:利用ImageJ分析荧光显微镜图像|QuPath基础教程1|24-08-08

内容概要 数字图像由像素组成&#xff0c;每个像素具有一个数值&#xff0c;通常与检测到的光线相关。相同的像素值可以通过不同的方式进行显示。在科学图像处理中&#xff0c;可以通过修改查找表来独立于像素值改变图像外观。 一、引言 图像由其最小的组成单位——像素构成。…...

Prompt Fuzzer:用于增强 GenAI 应用程序的开源工具

Prompt Fuzzer 是一个开源工具&#xff0c;可以评估GenAI应用程序的系统提示针对基于动态 LLM 的威胁的安全性。 Prompt Fuzzer 功能&#xff1a; 1. 模拟十几种类型的 GenAI 攻击。 2. 该工具会根据系统提示自动进行情境化&#xff0c;针对与 GenAI 应用程序相关的特定主题或行…...

Vision Pro使用GLFT 加载模型shader错误解决办法

Glft shader在vision pro上加载错误 前言相关背景解决办法 参考文章 前言 之前在Vision Pro上尝试加载Glb文件&#xff0c;但是加载完成后发现加载出来的Glb文件材质不正确。材质是黑色的。因此整理一下解决方案。 相关背景 使用Unity开发&#xff0c;Glb的加载插件为gltf F…...

Netty技术全解析:MessageToMessageCodec类深度解析

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…...

Three 【3D车模换肤】

目录 &#x1f31f;前言&#x1f31f;先看效果&#x1f31f;实现代码&#x1f31f;写在最后 &#x1f31f;前言 哈喽小伙伴们&#xff0c;最近工作比较忙一直没有给大家更新&#xff0c;新的专栏 Three.js第三篇&#xff0c;记录一下博主学习Three.js的过程&#xff1b;一起来…...

语言模型简介和Ngram模型(1)

语言模型介绍一 语言模型语言模型概念语言模型应用-语音识别声纹特征提取语言模型挑选成句 语言模型应用-手写识别语言模型应用-输入法语言模型分类语言模型评价指标-困惑度PPL N-gram语言模型马尔科夫假设平滑问题平滑问题解决一平滑问题解决二 插值优化语言模型应用-文本纠错…...

MessageBox弹框替代系统自带的alert、confirm -- 高仿ElementUI MessageBox

MessageBox 弹框 MessageBox 的作用是替代系统自带的 alert、confirm &#xff0c;仅适合展示较为简单的内容。如果需要弹出较为复杂的内容&#xff0c;请使用定制的弹窗。基本仿照ElementUI的同名组件。 原生&#xff0c;无依赖项&#xff0c;自适应布局&#xff0c;双端通用&…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...