[Java]0.1+0.2不等于0.3 !!一分钱问题与解决方案

一、原因

原因很简单,计算机存储和计算数组都是用二进制,
而大部分小数转二进制的时候,就丢失精度了。
0.1、0.2、0.3这些小数在二进制里都是循环小数,计算机不可能存储无限循环小数,所以只能截取一部分,导致本身失去精度。
计算机再用这些有误差的小数进行计算,那误差就更大了。

互转教程:十进制小数 与 二进制小数 互转


二、一分钱问题

假如用float和double进行金钱计算,因为二进制转换误差就很容易出现一分钱问题。

方案

方案1、 使用BigDecimal

BigDecimal a = new BigDecimal("0.1"); //切记!!参数一定要是字符串
BigDecimal b = new BigDecimal("0.2"); //切记!!参数一定要是字符串
BigDecimal c = a.add(b);
System.out.println(c);

切记!!
创建BigDecimal参数一定要是字符串
如果直接传参浮点数,计算机自动转二进制,同样会有误差!!!

方案2、 使用long

1、金钱保存到数据库时,金钱乘1000,字段类型为整型。
2、计算时就使用整型计算。
3、显示时金钱/1000。

long a = 0.1 * 1000;
long b = 0.2 * 1000;
long c = a + b;
System.out.println(c / 1000);

三、扩展知识 IEEE-754二进制

计算机浮点数标准。
它规定了浮点数的表示、运算和舍入方式等方面的规则。

1、IEEE-754二进制组成

类型符号位阶码尾数
float占1bit占8bit占23bit
double占1bit占11bit占52bit
  1. 符号位,0表示正数,1表示负数。
  2. 指数,浮点数的大小和符号的指数部分。127偏移量
  3. 尾数,浮点数的小数部分。

2、十进制float转IEEE-754二进制

步骤例子0.5例子-12
1获取【符号位】
0表示正数,1表示负数。
0.5是正数,符号位为0-12是负数,符号位为1
2十进制小数 转 二进制十进制0.5转二进制 0.1十进制-12转二进制 1100.011
3二进制转科学计数法
1.xx * 2 指数 2^{指数} 2指数
1.0 ∗ 2 − 1 1.0 * 2^{-1} 1.021 1.100011 ∗ 2 3 1.100011 * 2^3 1.10001123
4获取十进制指数值
127+指数
127+(-1)=126127 + 3 = 130
5 【指数值】 十进制 转 二进制
不满八位前面补0
126 ->01111110130 -> 10000010
6【尾数位】
科学计数法的 xx
不满23位后面补0
xx为0
补零:00000000 00000000 0000000
xx为100011
补零:10001100 00000000 0000000
7拼接 符号位+指数值+尾数位0 10000010 000000000000000000000001 10000010 10001100000000000000000

我们再用上面步骤计算float 0.1
请添加图片描述

  1. 0.1获取符号位,0.1正数为0。
  2. 0.1转二进制,0.00011001100110011001101(已失去精度)
  3. 科学计数法, 1.1001100110011001101 ∗ 2 − 4 1.1001100110011001101 * 2^{-4} 1.100110011001100110124
  4. 获取十进制指数值,127 + (-4) = 123
  5. 指数值 转 二进制,123 -> 01111011
  6. 尾数位补零,10011001 10011001 101
  7. IEEE-754二进制:0 01111011 1001100110011001101

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

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

相关文章

中文连续视觉语音识别挑战赛

视觉语音识别,也称唇语识别,是一项通过口唇动作来推断发音内容的技术。该技术在公共安全、助老助残、视频验真等领域具有重要应用。当前,唇语识别的研究方兴未艾,虽然在独立词、短语等识别上取得了长足进展,但在大词表…

从创业者的角度告诉你AI问答机器人网页的重要性

在数字化时代,创业者面临着越来越多的挑战。而AI问答机器人网页正成为创业者们的必备工具。它可以提供即时客户支持、降低运营成本,并实现全天候服务。接下来,我将从创业者的角度阐述一下,AI问答机器人网页为什么那么重要&#xf…

快速自动化处理JavaScript渲染页面的方法

目录 一、使用无头浏览器 二、使用JavaScript渲染引擎 三、使用前端框架工具 随着互联网技术的不断发展,JavaScript已经成为Web开发中不可或缺的一部分。然而,在自动化处理JavaScript渲染页面方面,却常常让开发者感到头疼。本文将介绍一些快…

Nessus已激活,New Scan按钮不可点击

刷新后会给出下面的提示 Plugins are compiling. Nessus will be limited until compilation is complete. 因为插件编译中,所以扫描功能被禁用了。 查看编辑进度,鼠标放到两个循环箭头上即可查看。

6.4 图的存储结构

思维导图: 前言: --- **6.4 图的存储结构** - **核心问题**:由于图的结构复杂性,我们不能仅仅依赖于元素在存储区的物理位置来表示它们之间的关系。 - **邻接矩阵**: - **基本思路**:虽然图没有顺序存…

Junit 单元测试之错误和异常处理

错误和异常处理是测试中非常重要的部分。假设我们有一个服务,该服务从数据库中获取用户。现在,我们要考虑的错误场景是:数据库连接断开。 整体代码示例 首先,为了简化,我们让服务层就是简单的类,然后使用I…

[Machine Learning][Part 6]Cost Function代价函数和梯度正则化

目录 拟合 欠拟合 过拟合 正确的拟合 解决过拟合的方法:正则化 线性回归模型和逻辑回归模型都存在欠拟合和过拟合的情况。 拟合 来自百度的解释: 数据拟合又称曲线拟合,俗称拉曲线,是一种把现有数据透过数学方法来代入一条…

浅谈大数据之Flink-2

1.5 流处理基础概念 在某些场景下,流处理打破了批处理的一些局限。Flink作为一款以流处理见长的大数据引擎,相比其他流处理引擎具有众多优势。本节将对流处理的一些基本概念进行细化,这些概念是入门流处理的必备基础,至此你将正式进入数据流的世界。 1.5.1 延迟和吞吐 …

PHP框架开发实践 | 1024 程序员节:通过index.php找到对应的controller是如何实现的

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师…

STM32CubeMX之DMA辅助串口数据接收

1.DMA辅助串口数据接收 1.1 DMA简介 直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。   两个DMA控制器有12个通道(DMA1有7个通道&am…

什么是网络爬虫,爬虫的机制是那些

网络爬虫(也称为网页蜘蛛、网络机器人或网页追逐者)是一种按照预设规则,自动抓取万维网信息的程序或脚本。它们广泛应用于搜索引擎、数据挖掘、竞争情报、价格监测等各种互联网应用中。 爬虫机制是爬虫程序或机器人用来访问、抓取、索引以及…

前端Javascript | 数组值随机选择函数

文章目录 目的解决方案 目的 为了解决 postman 传参数据定制化,需要写一点前置脚本,有用到随机选取数组中的值来造数据。 解决方案 // 随机数组函数 function getRandomNumber(arr) {return arr[Math.floor(Math.random() * arr.length)]; }

2023年中国清净剂行业需求现状及前景分析[图]

清净剂用于中和由于燃烧和润滑油氧化产生的酸性物质,并清除颗粒和污物。这类杂质在油中的溶解度有限,因此,清净剂可以最大程度减少沉积物的生成,降低污染,提高环保排放标准。成熟产品有磺酸盐、硫化烷基酚盐、烷基水杨…

yolov作者简介

作者简介 作者叫Joseph Redmon,在谷歌学术上搜索作者的简介。 地址:‪Joseph Redmon‬ -巨人学术搜索‬‬ (cljtscd.com) 他提出了最著名的YOLO算法。其中YOLOV1的引用量达到了40287次。 gitihub地址:github地址 主页:个人主页

workerman 运行时报错 Call to undefined function posix_getpid()

使用 验证php扩展是否齐全 curl -Ss https://www.workerman.net/check | php缺少posix 下载 在 Linux 系统上,可以使用包管理器来安装 php-posix 扩展,例如 Ubuntu 系统可以通过以下命令进行安装: sudo apt-get install php-posix如果你使用…

LeetCode 2895. 最小处理时间【贪心,排序】1351

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

ims-ui项目搭建

node版本: npm版本: 创建vite项目: npm create vitelatest 使用的vite版本为: 安装router4,安装命令如下: npm install vue-router4 安装pinia,安装命令如下: npm install pinia 安装Pinia持…

【Linux】adduser命令使用

我们经常在linux系统中创建用户。有时候用的是 useradd 有时候用的是 adduser ,好混乱啊到底用哪个啊。今天咱们一起来学习一下。 adduser与useradd的区别 useradd 命令是内置的 Linux 命令,在任何 Linux 系统中都可用。然而,使用这种低级…

ssm+vue基本微信小程序的今日菜谱系统

项目介绍 谈到外出就餐,我们除了怕排队,也怕这家餐厅的服务员不够用,没人为我们点餐,那么一餐饭排队一小时,点餐恐怕也要花个半小时,这样不仅给消费者的用餐体验大打折扣同时也给商家的口碑造成了严重负面…

代码覆盖率统计Super-jacoco在公司级容器化项目中的具体应用方案

目录 一、介绍 二、自己在本地搭建Super-jacoco服务 2.1 准备工作 2.2 部署super jacoco服务 1、下载super jacoco 项目 2、初始化数据库 3、配置application.properties 4、编译super jacoco项目 5、部署 super jacoco 服务 2.3 启动被测项目 2.4、代码覆盖率收集 2…