【你真的了解double和float吗】

在这里插入图片描述

🌈个人主页:努力学编程’
个人推荐:基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解
学好数据结构,刷题刻不容缓:点击一起刷题
🌙心灵鸡汤总有人要赢,为什么不能是我呢
!=外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

🌈🌈🌈一些有关float和double的奇怪现象

  • 现象一:条件判断超出预期
System.out.println(1f==0.9999999f);//输出结果  falseSystem.out.println(1f==0.99999999f); //输出结果  true
  • 现象二:数据转换超出预期
float f =1.1f;
double d=(double)f;
System.out.println(f);// 输出1.1
Sysout.out.println(d);// 输出1.100000023841858
  • 现象三: 基本计算超出了预期
System.out.println(0.2+0.7);
//输出  0.8999999999999999
  • 典型现象四:数据自增超出预期
float f1=8455263f
for(int i=0;i<10;i++){Sysout.out.println(f1);f1++;
} //此处正常打印f1相加后的值float f2=84552631f;
for(int i=0;i<10;i++){Sysout.put.println(f2);f2++;
}//输出的结果  8.4552632E7 //后面的每次运算之后结果仍为 8.4552632E7 

以上情况,我们会发现其实关于float和double很多基础的操作,都可能会出现问题,所以公司或者银行系统一般不会将商品金额,订单交易,货币计算使用float或者double,浮点数的风险很大!!!

🌈🌈🌈原因分析

为什么会出现这些的情况呢,其实这就和java中存储浮点数的方式有关了,由于存储方式的缺陷往往会把浮点数的数据丢失。

分析现象一:

Sysout.out.println(1f==0.99999999f);  //输出  true

为何判断 1 和 0.99999999 的大小输出true?

我们知道关于1和0.99999999我们通过肉眼直接可以判断两者之间的关系,这里我们都是默认的是十进制进行的大小比较,但是计算机的底层逻辑都是基于1010010101这样的二进制形式进行存储数据的。

所以我们可以试图将这两个数转化为二进制,然后再进行大小的比较:
在这里插入图片描述
这是一个进制转换的网站:进制转换网站

🌈🌈🌈浮点数精度的问题

学过 《计算机组成原理》 这门课的小伙伴应该都知道,浮点数在计算机中的存储方式遵循IEEE 754 浮点数计数标准,可以用科学计数法表示为:
在这里插入图片描述

只要给出:符号(S)、阶码部分(E)、尾数部分(M) 这三个维度的信息,一个浮点数的表示就完全确定下来了,所以float和double这两种浮点数在内存中的存储结构如下所示:
在这里插入图片描述

⚡⚡⚡符号部分(s):

由0和1构成,0代表该数为正,1代表该数为负。

⚡⚡⚡阶码部分(E):

  • 针对float这种浮点数,他的指数部分有8位,可表示正数,也可以表达负数,因此,可以表述的指数的范围是-127~128
  • 对于double类型的浮点数,指数部分的大小为11位,这里既可以是正数也可以是负数,所以这里可以表示的指数范围是-1023~1024

⚡⚡⚡尾数部分(M)

其实一个浮点数的精度就是由尾数的尾数决定的:

  • 对于float形的浮点数,尾数部分有23位,换算成十进制就是2^23=8388608,所以十进制的精度就只有6~7位
  • 对于double形的浮点数,尾数部分有52位,换算成十进制就是2^52=450359962737049,所以对应的十进制的精度就只有15到16位

所以我们上面说的例子中的数值0.99999999f,很明显已经超过了float型浮点数数据的精度范围,所以出现问题也是可以理解的。

⚡⚡⚡如何解决精度的问题

如果我们在日常的开发过程中涉及到商品金额,交易值,货币计算等一些对精度要求较高的场景应该怎么办呢?

方法一:使用字符串或者数组解决多位数的问题

相信如果你大量刷过算法题的话,应该都知道使用字符串或者数组代表大数是一个典型的解题思路。

这时候我们我们可以用字符串或者数组来表示这种大数,然后按照四则运算的规则来手动模拟出具体计算过程,中间还需要考虑各种诸如:进位、借位、符号等等问题的处理,确实十分复杂,本文不做赘述。

方法二:使用java大数类
JDK早已为我们考虑到了浮点数的计算精度问题,因此提供了专用于高精度数值计算的大数类来方便我们使用。Java的大数类位于java.math包下:
在这里插入图片描述
可以看到,常用的BigInteger 和 BigDecimal就是处理高精度数值计算的一种很有效的方法。

BigDecimal num3 = new BigDecimal( Double.toString( 1.0f ) );
BigDecimal num4 = new BigDecimal( Double.toString( 0.99999999f ) );
System.out.println( num3 == num4 );  // 打印 falseBigDecimal num1 = new BigDecimal( Double.toString( 0.2 ) );
BigDecimal num2 = new BigDecimal( Double.toString( 0.7 ) );// 加
System.out.println( num1.add( num2 ) );  // 打印:0.9// 减
System.out.println( num2.subtract( num1 ) );  // 打印:0.5// 乘
System.out.println( num1.multiply( num2 ) );  // 打印:0.14// 除
System.out.println( num2.divide( num1 ) );  // 打印:3.5

但是,BigInteger 和 BigDecimal这种大数类的运算效率相对于原生类型效率高,代价还是比较高的,所以大家要理性使用~

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

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

相关文章

腾讯云函数node.js返回自动带反斜杠

云函数返回自动带反斜杠 这里建立了如下一个云函数,目的是当APP过来请求的时候响应支持的版本号: use strict; function main_ret(status,code){let ret {status: status,error: code};return JSON.stringify(ret); } exports.main_handler async (event, context) > {/…

Buuctf之不一样的flag(迷宫题)

首先&#xff0c;进行查壳无壳&#xff0c;32bit&#xff0c;丢进ida32中进行反编译进入main函数&#xff0c;对其进行分析&#xff0c;可以在一旁打上注释&#xff0c;这边最关键的一个点就是&#xff0c;需要联想到这是一个迷宫题&#xff0c;很小的迷宫题&#xff0c;迷宫就…

(十三)MipMap

MipMap概念 滤波 采样 mipmap级别判定 问题&#xff1a;opengl如何判定应该使用下一级的mipmap呢&#xff1f; 通过glsl中的求偏导函数计算变化量决定 手动实现mipmap原理 1、生成mipmap的各个级别 2、修改vertexShader使得三角形随着时间变小 **** 需要更改Filter才能…

事务底层与高可用原理

1.事务底层与高可用原理 事务的基础知识 mysql的事务分为显式事务和隐式事务 默认的事务是隐式事务 显式事务由我们自己控制事务的开启&#xff0c;提交&#xff0c;回滚等操作 show variables like autocommit; 事务基本语法 事务开始 1、begin 2、START TRANSACTION&…

透过 Go 语言探索 Linux 网络通信的本质

大家好&#xff0c;我是码农先森。 前言 各种编程语言百花齐放、百家争鸣&#xff0c;但是 “万变不离其中”。对于网络通信而言&#xff0c;每一种编程语言的实现方式都不一样&#xff1b;但其实&#xff0c;调用的底层逻辑都是一样的。linux 系统底层向上提供了统一的 Sock…

三菱PLC标签使用(I/O的映射)与内容

今天&#xff0c;小编继续开始三菱PLC的学习&#xff0c;今天的内容是标签及其标签的内容说明&#xff0c;如果对你有帮助&#xff0c;欢迎评论收藏。 标签的种类&#xff0c;等级&#xff0c;定义 种类 三菱3U的PLC的种类分别为二种&#xff1a;全局标签与局部标签 全局标签…

操作审计(一)

操作审计&#xff08;一&#xff09; 前言一、快速查询事件二、高级查询事件总结 前言 这里主要记录操作审计的过程&#xff0c;操作审计其实就是监控并记录阿里云账号的活动&#xff0c;可以使用阿里云的操作审计服务来审计最近90天阿里云账号下的操作&#xff0c;从而确保云…

Java AI 编程助手

Java AI 编程助手是指利用人工智能技术来增强和优化Java开发过程中的各种任务和活动。它可以涵盖从代码生成和分析到测试和优化的多个方面&#xff0c;帮助开发人员提高生产效率、降低错误率&#xff0c;并优化代码质量和性能。 ### 功能和特点 1. **智能代码生成和建议**&am…

如何在 SCSS 中实现复杂的嵌套选择器并确保代码的可维护性?

在 SCSS 中实现复杂的嵌套选择器时&#xff0c;可以遵循以下几个原则以确保代码的可维护性&#xff1a; 限制嵌套层级&#xff1a;避免层级过深的嵌套&#xff0c;最好不要超过三级。过多的嵌套会增加代码的复杂性和选择器的特异性&#xff0c;降低代码的可读性和维护性。 使用…

等保2.0是否强制要求所有物联网设备都必须支持自动更新?

等保2.0对物联网设备自动更新的要求 等保2.0&#xff08;网络安全等级保护2.0&#xff09;是中国政府为了加强网络安全而推出的一套标准和要求。在物联网设备的安全管理方面&#xff0c;等保2.0确实提出了一系列措施&#xff0c;以确保设备的软件安全更新。这些措施包括&#…

RKNN3588——YOLOv8的PT模型转RKNN模型

一&#xff1a;PT转ONNX 1. 首先克隆rknn修改后的ultralytics版本项目到本地 https://github.com/airockchip/ultralytics_yolov8 cd ultralytics-main pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple pip install -e . 主要是修改了源码的ul…

如何使用find查找命令

Linux查找命令是类Unix操作系统中最重要且最常用的命令行实用程序之一。查找命令可以根据你设定的参数匹配的文件指定的条件来搜索和查找文件或目录的列表。 查找可以在多种条件下使用&#xff0c;例如可以按权限&#xff0c;用户&#xff0c;组&#xff0c;文件类型&#xff…

JAVA声明数组

一、声明并初始化数组 直接初始化&#xff1a;在声明数组的同时为其分配空间并初始化元素。 int[] numbers {1, 2, 3, 4, 5}; 动态初始化&#xff1a;先声明数组&#xff0c;再为每个元素分配初始值。 double[] decimals;decimals new double[5]; // 分配空间&#xff0c;但…

PhpStorm 2024 for Mac PHP集成开发工具

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff08;适合自己的M芯片版或Intel芯片版&#xff09;&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功3、打开访达&#xff0c;点击【文…

锁之Syncronized(java面经)

在Java中&#xff0c;锁机制是用于管理多线程环境下的资源访问&#xff0c;以确保数据的一致性和完整性。Java提供了多种锁的实现方式&#xff0c;包括但不限于&#xff1a; 锁从宏观上分类&#xff0c;分为悲观锁与乐观锁。 乐观锁: 即读多写少 , 并发的可能性小 , 一般只有…

大数据面试题之Flink(1)

目录 Flink架构 Flink的窗口了解哪些&#xff0c;都有什么区别&#xff0c;有哪几种?如何定义? Flink窗口函数&#xff0c;时间语义相关的问题 介绍下Flink的watermark(水位线)&#xff0c;watermark需要实现哪个实现类&#xff0c;在何处定义?有什么作用? Flink的…

如何在TikTok上获得更多观看量:12个流量秘诀

TikTok作为热门海外社媒&#xff0c;在跨境出海行业中成为新兴的推广渠道&#xff0c;但你知道如何让你的TikTok赢得更多关注次数吗&#xff1f;如果您正在寻找增加 TikTok 观看次数的方法&#xff0c;接下来这12种策略&#xff0c;你需要一一做好&#xff01; 1. 在内容中添加…

HQ-SAM

不建议复现

鸿蒙开发设备管理:【@ohos.update (升级)】

升级 说明&#xff1a; 本模块首批接口从API version 6开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 升级范围&…

argparse大坑之parser

parser.add_argument(--rate,help"--rate 0.5 means that there is a 50% probability;",typefloat,default0.5)此时用-h输出usage会报错如下&#xff1a; 最后发现是因为parser的help里面出现了%&#xff0c;改了之后就好了。真坑啊&#xff01;