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

news2025/7/9 3:53:05

一、原因

原因很简单,计算机存储和计算数组都是用二进制,
而大部分小数转二进制的时候,就丢失精度了。
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.coloradmin.cn/o/1103457.html

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

相关文章

Linux网络-UDP/TCP协议详解

Linux网络-UDP/TCP协议详解 2023/10/17 14:32:49 Linux网络-UDP/TCP协议详解 零、前言一、UDP协议二、TCP协议 1、应答机制2、序号机制3、超时重传机制4、连接管理机制 三次握手四次挥手5、理解CLOSE_WAIT状态6、理解TIME_WAIT状态7、流量控制8、滑动窗口 丢包问题9、拥塞控制…

如何使用前端框架(React、Angular、Vue.js等)?该如何选择?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

“小”Bug,大能量

文章目录 简介BUG集(持续更新)依赖版本不一致配置错误循环依赖内存泄漏并发问题空指针异常依赖版本冲突 总结 简介 在写代码的时候,遇到了一些bug,在当下怎么检查都查不出问题出现在哪,等过几天后突然发现困扰自己的问…

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

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

数仓建设(三)

4) 累积快照事实表 多个业务过程联合分析而构建的事实表,如采购单的流转环节。用于分析事件时间和时间之间的间隔周期。少量的且当前事务型不支持的,如关闭、发货等相关的统计。 4. DWS公共汇总层设计规范 数据仓库的性能是数据仓库建设是否成功的重要标…

从头开始机器学习:逻辑回归

一、说明 本篇实现线性回归的先决知识是:基本线性代数,微积分(偏导数)、梯度和、Python (NumPy);从线性方程入手,逐渐理解线性回归预测问题。 二、逻辑回归简介 我们将以我们在线性回…

Memory Analyzer分析内存溢出

一、下载和安装 访问Eclipse MAT官网,下载适用于你操作系统的最新版本的MAT,并进行安装。 二、使用 2.1 导出Heap Dump文件 2.1.1 使用jmap命令导出Heap Dump文件 可以在终端或命令提示符中执行以下命令: jmap -dump:formatb,file/path/to/heapdum…

JSONObject和JSONArray区别及注意事项

1、JSONObject和JSONArray的数据表示形式 JSONObject的数据是用 { } 来表示的, 例如: {"name":"John","age":30,"city":"New York"}而JSONArray,顾名思义是由JSONObject构成的数组&…

NSS [BJDCTF 2020]easy_md5

NSS [BJDCTF 2020]easy_md5 先看题目,给了一个输入框 翻阅了源码没发现什么可疑点 扫一下试试,也没东西 抓个包试试,在响应头发现了hint 那就是奇妙的md5了,输入ffifdyop 原理: ffifdyop的MD5加密结果是276f722736c…

探索音频传输系统:数字声音的无限可能 | 百能云芯

音频传输系统是一项关键的技术,已经在数字时代的各个领域中广泛应用,从音乐流媒体到电话通信,再到多媒体制作。本文将深入探讨音频传输系统的定义、工作原理以及在现代生活中的各种应用,以帮助您更好地了解这一重要技术。 音频传输…

SDK入门

目录 控制台程序 与 Windows程序 Windows程序与Console程序入口的区别 代码编写区别 SDK 基本概念 VS2019 SDK VS2019创建桌面应用程序 ANSI 与 Unicode TCHAR char wchat_t 解决编码的影响 MessageBox() 第一个SDK程序 MessageBox函数 控制台程序 与 Windows程序 …

PPC-R22.1N-T-Q2-G2-NN-FW 使用反馈来解决误差和系统干扰

PPC-R22.1N-T-Q2-G2-NN-FW 使用反馈来解决误差和系统干扰 伺服机构是自动控制系统,用于从数控机床,机器人技术,仓库自动化还有更多。与开环系统相比,带伺服驱动器的闭环系统在运动应用中具有更高的可靠性和精度。怎么会&#xff…

Spring系列综合

目录 1 Spring介绍2 Spring核心技术3 Spring入门案例3.1 Spring jar包下载(了解)3.2 通过mven方式导入jar包3.3 编辑application.xml文件3.4 编辑测试类 4 Spring核心技术IOC4.1 什么是IOC4.2 IOC实现原理 5 Spring创建对象方式5.1 静态工厂模式5.1.1 编辑静态工厂类5.1.2 编辑…

请求分页管理方式(页表机制,缺页中断,地址变换)

请求分页存储管理与基本分页存储管理的主要区别: 在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序。(操作系统要提供请求调页功能,将缺失页面从外存调入内存)若…

MapReduce任务个数如何影响执行效率?性能优化从这里做起

在正文开始之前,请先来回答一下这个问题: 题目:输入为3个文件,a.txt 300MB,b.txt 100MB,c.txt 58.MB,使用MapReduce的example程序,计算Wordcount,请问,应该有多少个MapTask&#xf…

分享一种非隔离控制三象限双向可控硅的产品级电路

上图是一款在美国卖得很火的挂烫机的电源电路和双向可控硅控制电路,可以看到电源部分采用的是阻容降压,阻容降压电路适用于低成本小电流的应用场合,根据电容容抗的计算公式Xc1/(2πfC) 可算出容抗大小,(f为市电的频率5…

编译和链接(小白初理解)

目录 1. 翻译环境和运⾏环境 1.2翻译环境 2. 翻译环境:预编译编译汇编链接 2.1预处理(预编译)阶段 2.2编译 2.2.1词法分析 2.2.2语法分析 2.2.3语义分析 2.3 汇编 2.4 链接 3. 运⾏环境 1. 翻译环境和运⾏环境 翻译环境指的是&a…

设计模式截图记录

设计模式截图记录

GeoServer改造Springboot启动五(解决接口返回xml而不是json)

请求接口返回的是xml,而不是我们常用的json,问题呈现如下图 40 图 40请求接口返回XML 在RequestMapping注解上增加produces {MediaType.APPLICATION_JSON_UTF8_VALUE} 图 41增加produces