java运算中的精度问题

0.59f * 100 和 0.59 * 100

上面两个运算公式的运算结果如下:

        int a1 = (int) (0.59f * 100);
        System.out.println(a1); // 输出:58
        int a2 = (int) (0.59 * 100);
        System.out.println(a2); // 输出:59

java中小数不带标识默认是double类型

好家伙,这是为啥呢,第一个居然是58,由于不明白上面的运算问题,一到简单题我愣是没搞出来😂。
上面的运算中使用了float和double来进行小数运算,但是还记得有句话是这样说的,使用float和double会有精度丢失,网上搜了搜才知道,上面的问题就正好遇到了float运算精度丢失的问题。而恰好double没有丢失精度。
为什么这样计算会丢失精度,先一起复习下计算机中二进制和十进制的转换:

二进制基础知识:

二进制数和10进制数字的相互转换

二进制数转为10进制数:
在这里插入图片描述
10进制转为2进制数:
在这里插入图片描述
当然上面的0.625只是刚好可以表示为二进制,并没有精度损失的问题,

计算机对浮点数的存储

IEEE754是一个最广为使用的浮点数运算标准,
在这里插入图片描述
在这里插入图片描述
图片出处: https://blog.csdn.net/user2025/article/details/107746452
float和double表示的数值的精度范围:
在这里插入图片描述
参考: https://baike.baidu.com/item/IEEE%20754/3869922?fr=aladdin

而对于我们上面计算公式中的0.59转为二进制表示为:

十进制小数基数取整
0.5921.181
0.1820.360
0.3620.720
0.7221.441
0.4420.880
0.8821.761

再往下按照二进制转10进制的规则,可以一直计算得到(自己借助这个 平台计算的)

0.59=0.10010111000010100011110101110000101000111101011100001

因为floatM只有23位,外加开头默认的1,一共可以存储24位,即计算的时候实际使用的是:
0.10010111 00001010 00111101 参与运算,这样的话结果就为58了,
上面的小数部分刚好为53位,所以用double类型计算没有出现错误。

避免精度丢失:

使用float和double运算时会造成结果的不准确,因此浮点数运算的时候,我们可以使用java提供的BigDecimal,使用BigDecimal对小数进行运算的时候,会先将数字扩大N倍,同时保存精度,转为整数进行相应的运算,最后再转为小数。
题目: https://leetcode.cn/problems/percentage-of-letter-in-string/
当然这道题使用double也可以

   public int percentageLetter(String s, char letter) {
        int frequent = 0;
        char[] chars = s.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            if (chars[i] == letter) {
                frequent++;
            }
        }
        if (frequent == 0) {
            return 0;
        }
        if (frequent == s.length()) {
            return 1;
        }
        BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(frequent));
        BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(s.length()));
        return (int) (bigDecimal1.divide(bigDecimal2, 4, RoundingMode.FLOOR).multiply(new BigDecimal("100")).doubleValue());
    }

两个数相除得到double类型

下面的代码:

        double b = 499999999d / 500000000;
        System.out.println("b is:" + b);
        double c = 499999998d / 499999999;
        System.out.println("c is:" + c);

在我的电脑上输出是:

b is:0.999999998
c is:0.999999998

这两个小数我的电脑计算出来的结果是相等,但是leetcode提交过不了,我应该算错了,
如果 y1/x1=y2/x2,那么转换为乘法,y1x2=y2x1,
转换为下面的公式:

	    long d = 499999999L * 499999999;
        long e = 499999998L * 500000000;
        System.out.println(d);
        System.out.println(e);

输出:

249999999000000001
249999999000000000

这样计算又是不相等的,那到底是哪个错了?再使用BigDecimal进行除法运算计算下,看下准确的结果,根据上面的公式double最多保留15.95位十进制数,这里使用BigDecimal运算的时候我保留20位的小数

        BigDecimal dec1 = new BigDecimal(String.valueOf(499999998));
        BigDecimal dec2 = new BigDecimal(String.valueOf(499999999));
        BigDecimal dec3 = new BigDecimal(String.valueOf(499999999));
        BigDecimal dex4 = new BigDecimal(String.valueOf(500000000));

        System.out.println(dec1.divide(dec2, 20, RoundingMode.FLOOR).toString());
        System.out.println(dec3.divide(dex4, 20, RoundingMode.FLOOR).toString());

输出:

0.99999999799999999599
0.99999999800000000000

可以看到,499999998d / 499999999 计算的结果对比用BigDecimal计算的结果,结果小数部被舍弃了一些,所以导致最终的结果错误,因此计算double除法的时候要小心,进行下公式转换,或使用BigDecimal。
参考:
https://cloud.tencent.com/developer/article/1470383
https://blog.csdn.net/user2025/article/details/107746452
题目:
https://leetcode.cn/contest/weekly-contest-294/

liu_12345_liu
关注 关注
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java-关于基本数据类型浮点数计算产生的精度问题
12-22
简单关于BigDecimal类 在基本数据类型,float和double都表示浮点型数据,而计算机计算采取的是对二进制的计算,所以会存在一定程度上的精度丢失问题。 BigDecimal类是一个大小数操作类,可以用来对超过16位有效位的数据进行精确的运算,在这里我们使用BigDecimal类来解决浮点数计算产生的精度丢失问题精度问题 在这里我们讨论一个问题:3 – 2.7 == 0.3 的值是什么? 首先对表达式进行分析,该表达式有两个运算符,分别为减运算符 -和关系运算符 = = ,由于减运算符 – 的优先级高于关系运算符,所以该表达式将输出一个布尔值,即输出一个true或者false,
Java浮点类型存储,精度丢失及其解决方法
敢问路在何方,路在脚下
03-24 558
Java的浮点类型有两种:float和double。
如何解决Java 精度问题
最新发布
qq_33326733的博客
05-15 1003
Java 编程,处理浮点数和超大整数时常常会遇到精度丢失和数值溢出的困扰。为了确保计算结果的精确性,尤其是在金融计算等对精度要求极高的场景,我们需要使用BigDecimal和BigInteger类。本文将详细介绍浮点数精度丢失的原因、如何解决该问题,以及如何处理超出long范围的整数。
javadouble类型数据加减操作精度丢失问题及解决方法
程序员子龙
03-05 709
但是想像一下吧,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?在使用Javadouble 进行运算时,经常出现精度丢失的问题,总是在一个正确的结果左右偏0.0000**1。今天在项目用到double类型数据加减运算时,遇到了一个奇怪的问题,比如1+20.2+300.03,理论上结果应该是321.23,其实结果并不是这样。
JavaJavaBigDecimal解决精度丢失问题
DreamSun的博客
10-09 1132
可以看到在Java进行浮点数运算的时候,会出现丢失精度问题。那么我们如果在进行商品价格计算的时候,就会出现问题。很有可能造成我们手有0.06元,却无法购买一个0.05元和一个0.01元的商品。因为如上所示,他们两个的总和为0.060000000000000005。这无疑是一个很严重的问题,尤其是当电商网站的并发量上去的时候,出现的问题将是巨大的。可能会导致无法下单,或者对账出现问题。所以接下来我们就可以使用Java的BigDecimal类来解决这类问题
解决java计算数字小数时丢失精度问题
Hellos_Worlds的博客
01-19 1093
package Java; import java.math.BigDecimal; public class BigDecimalUtil { //无参构造 private BigDecimalUtil() { } //将String字符串转换成double public static double strToDouble(String str) { return Double.valueOf(str); } //加 ...
java如何解决浮点数运算精度丢失问题
istianyz的博客
10-21 2091
java使用BigDecimal解决浮点数运算精度丢失问题
java计算缺失精度问题
m0_69733784的博客
05-29 3577
Java的浮点数类型为float和double,它们采用的是IEEE 754规范的浮点数编码,这种编码方式虽然能够表示大范围的实数,但存在一定的精度损失。BigDecimal类可以表示任意精度的十进制数,并提供了加减乘除等运算方法,能够避免浮点数精度问题和整数溢出问题。这是因为0.1和0.2都不能被精确表示为浮点数,它们的值会被近似表示,而相加结果的误差会积累,导致最终结果不准确。总之,在进行计算时,需要根据实际情况选择合适的数据类型,并使用正确的算法,以避免精度问题
Java精度丢失问题及解决方法
weixin_65091178的博客
05-18 2613
引入:小a某天突发奇想,如果我用计算机输出0.1+0.2,那么会输出0.3吗?恭喜你,得到结果:0.30000000000000004!可是这次的输出结果竟然是正确的3.0!为什么呢?不仅仅是Java,在C++、JavaScript等各种带浮点数计算的语言都会出现这样的问题。其实是因为在数的进制转换过程出现了问题!什么是精度丢失?
java基础-小数计算为什么不精确
RedPig的专栏
04-01 1503
违反直觉 计算机之所以叫"计算"机就是因为发明它主要是用来计算的,"计算"当然是它的特长,在大家的印象,计算一定是非常准确的。但实际上,即使在一些非常基本的小数运算,计算的结果也是不精确的。 比如: float f = 0.1f*0.1f; System.out.println(f); 这个结果看上去,不言而喻,应该是0.01,但实际上,屏幕输出却是0.010000001,后面多了个1。 看上去这么简单的运算,计算机怎么会出错了呢? 为什么会出错呢? 实际上,不是运算本身会出错,而是计算机根本就不能精
JavaBigDecimal类型小数精度丢失问题,利用 NumberUtil 工具进行金额格式化、千位分隔等操作
hkl_Forever的博客
02-10 3137
1、上述结果可以看出,使用 BigDecimal.valueOf 转换方式,在参数为字符串整数的时候,需要先转成 Double 类型,再转成 BigDecimal 类型。在开发,经常会遇到数值计算类的业务,就会用到 BigDecimal 类型,但是需要注意涉及小数的数值可能会出现精度丢失问题,导致计算结果不精准。上述结果可以看出,使用 new BigDecimal 转换方式,在参数为非字符串小数的时候,会出现精度丢失问题。2、如果需要转换的是字符串类型,推荐 new BigDecimal 方式。
Java Double 精度问题总结
09-25
使用Java,double 进行运算时,经常出现精度丢失的问题,总是在一个正确的结果左右偏0.0000**1。 特别在实际项目,通过一个公式校验该值是否大于0,如果大于0我们会做一件事情,小于0我们又处理其他事情。 这样的...
Java 加减乘除工具类(解决精度损失问题
07-18
//精度为2,舍入模式为大于0.5进1,否则舍弃 BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1....
javascript的float运算精度实例分析
12-09
有人问到一个js问题: 代码如下: var i = 0.07; var r = i*100; alert(r); 结果为什么是7.0000000000000001? 查了下资料,其实我们知道JavsScript,变量在存储时并不区分number和float类型,而是统一按...
java和js的计算精度的实现
09-22
在金额的加减乘除运算时我们往往会忽略计算结果的精度问题,导致莫名奇妙出现了过多的小数位,这在我做银行项目时尤其需要关注的一个问题点。 其实在我们使用正常的 + - * / 运算时,在某些情况下就会出现精度丢失...
sjmp:安全的Java精度
05-22
SJMP旨在提供一套适用于实施加密软件的多精度算术运算。 为此,在执行时间不取决于操作数的值的意义上(尽管它可能取决于操作数的长度)在意义上已经特别注意确保操作是“恒定时间”的。 作为次要考虑,已经花费一些...
Javadouble保留2位小数(精度丢失)的两种方式
热门推荐
weixin_50989469的博客
08-31 1万+
对于double数据类型进行计算发生的精度丢失的情况,可以按照自己的需求选择任意方式,方式一更灵活点,方式二可以直接得到字符串类型的结果
java、js对小数的运算(防止精度丢失)
var200的博客
09-01 633
JAVA /** * double 相加 * @param d1 * @param d2 * @return */ public static double sum(double d1,double d2){ BigDecimal bd1 = new BigDecimal(Double.toString(d1)); BigDecimal bd2 = new BigDecimal(Double.toSt
java小数精度_Java的小数运算精度损失
weixin_39991305的博客
02-15 498
float、double类型的问题我们都知道,计算机是使用二进制存储数据的。而平常生活,大多数情况下我们都是使用的十进制,因此计算机显示给我们看的内容大多数也是十进制的,这就使得很多时候数据需要在二进制与十进制之间进行转换。对于整数来说,两种进制可以做到一一对应。而对于小数来讲就不是这样的啦。我们先来看看十进制小数转二进制小数的方法对小数点以后的数乘以2,会得到一个结果,取结果的整数部分(不是1...
java关于运算精度
04-02
Java有两种类型的数据类型:整数类型和浮点数类型。整数类型的运算精度可以保证...使用BigDecimal类可以避免浮点数运算精度问题,但需要注意的是,BigDecimal类的运算效率相对较低,因此在需要高精度计算时才应使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • python对字符串按照ascII码顺序排序 26254
  • java中对Map进行排序的方法 17747
  • vs报错strcpy不安全 8737
  • 和为k的最长子数组的长度 6176
  • Android混淆 4745

分类专栏

  • 用户增长
  • word快捷键
  • 各种排序算法的时间复杂度
  • 动态化
  • 骑行 1篇
  • 面试 2篇
  • 总结
  • java 11篇
  • linux
  • kafka
  • tools 1篇
  • html
  • spring 
  • mysql
  • dp
  • uploadify
  • algorithm 8篇
  • c++ 1篇
  • android 16篇
  • js
  • spring
  • spring boot
  • json
  • pycharm使用
  • python 1篇
  • tensorflow
  • 推荐系统
  • 数据结构和算法 2篇
  • 深圳租房坑
  • UML

最新评论

  • Android 开发部分基础工具使用

    普通网友: 文章结构严谨有条,层次分明,读起来一点也不费劲,让人受益匪浅。【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】

  • Android adb 日常使用指南

    CSDN-Ada助手: 哇, 你的文章质量真不错,值得学习!不过这么高质量的文章, 还值得进一步提升, 以下的改进点你可以参考下: (1)增加除了各种控件外,文章正文的字数;(2)使用更多的站内链接;(3)提升标题与正文的相关性。

  • Android 开发部分基础工具使用

    普通网友: 这篇文章真是一篇佳作!作者运用了生动有趣的语言,将枯燥的理论知识娓娓道来,让人如沐春风。【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】

  • Android 开发部分基础工具使用

    普通网友: 这篇文章是优质之作,内容充实,结构明晰,语言流畅且通俗易懂,适合广大读者阅读。【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】

  • Android 开发部分基础工具使用

    执笔人: 这篇文章介绍了在NDK调试过程中的一些技巧和解决方法,非常实用。特别是关于调试包中符号丢失的问题,提到了通过设置符号搜索路径和避免strip来解决。另外,对于一些报错情况,作者也给出了详细的解决方案,比如处理`SIGILL`错误的方法。我希望作者能够分享更多类似的经验和技巧,并且期待在他的博客中找到更多关于Android开发、调试和性能优化方面的内容。

大家在看

  • 11.泛型、trait和生命周期(上) 479
  • IPNV6
  • 2023年05月二级
  • 【重写SpringFramework】第一章beans模块:填充对象(chapter 1-6) 719
  • SwiftUI 6.0(Xcode 16)全新 @Entry 和 @Previewable 宏让开发妙趣横生

最新文章

  • lvalue / rvalue and lvalue reference / rvalue reference
  • Android C++ 开发调试 & LLDB 工具使用
  • Android 开发部分基础工具使用
2024年3篇
2023年10篇
2022年9篇
2021年10篇
2020年8篇
2019年23篇
2018年2篇
2017年1篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司阜新百度seo多少钱长沙百度竞价包年推广张掖建站公司崇左英文网站建设衡阳关键词按天计费价格九江网站优化按天收费报价无锡网站建设设计报价九江关键词排名报价醴陵网站推广系统报价平凉SEO按天计费横岗网站推广方案价格兴安盟网站改版报价邢台seo哪家好淮北SEO按天收费推荐乌海网站制作设计价格丹竹头设计网站公司黄石网站建设设计揭阳网络广告推广哪家好延安SEO按天计费报价广元网站优化软件大连设计网站价格海北SEO按天收费价格大运网站搭建推荐莱芜百度爱采购价格阳江外贸网站建设哪家好泰安百姓网标王岳阳网站推广多少钱滨州百度竞价推荐诸城网站推广系统哪家好泉州设计网站报价歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化