面试杀手-double精度问题 & 进制转换

场景模拟

先来看一段VCR (哦走错片场了… 是场景)

面试官: 请你打开IDEA 输出12.56 + 11.25的结果
我: 先愣了一会 啥也没想照做了

面试官: 好的, 你怎么解决这个问题?

我: 这是double精度丢失问题 因为double占用8个字节 然后… …(此处省略内心煎熬过程)

面试官: 你先想想如何解决

我: 我想到的是我项目使用的BigDecimal解决的

面试官: 嗯 说说它是怎么实现 并告诉我为什么double会丢失精度?

我: … … (故作思考一会, 面试官说那我们跳过这道题吧… 心里想 这下裂开了)

…省略后续细节

由此有了笔者这篇文章捏, 下面就开始刨根问底式分析double精度问题

为什么double 的小数部分有效位是15-16 ?

这张图花了老夫2个小时 时间整理分析 请从上面往下看 切记!

注意:

1.上面说的占用位数是指 小数部分的有效位!

2.对于出现有效位是15的情况 得看编译器 至少我通过idea和eclipse测试下 都是15位

 //原题double res = 12.56 + 11.25;System.out.println(res);  //23.810000000000002

3.有兴趣的童鞋 可以根据我这个画画float的情况


为什么double参与计算时会有精度丢失问题?

上面提到 对于64位的浮点数来说 尾数也就是纯小数部分 占52位 注意这是二进制位数 我们编译得出来的是10进制形式位数即16!

所以呢无论你最终计算的结果有多少有效位 我都会取16位, 倘若你刚好计算的位数 <= 16 那皆大欢喜 可是当计算的位数 > 16 那精度不就丢失了?

在说明丢失问题之前需要补充一下进制转换的事情:

对于进制转换: 以10进制 数 转 二进制 为例 这里探讨的是实数情况 即包括 整数 和 小数部分

整数部分: 辗转除2 逆序取余 直到商为0

小数部分: 按为乘2 顺序取整 直到乘积 为0

文字理论都是苍白无力的, 来个demo

//以12.56 转为 二进制为例
整数部分:
12 / 2 -> 6(商) .... 0 (余数)
6 / 2 ->  3 ........ 0
3 / 2 ->  1 ........ 1
1 / 2 ->  0 .........1
故12(十进制) -> 1100(二进制)
小数部分
0.56 * 2 ->1.12(乘积)  ..... 1(取整)
0.12 * 2 -> 0.24 ............0
0.24 * 2 -> 0.48 ............0
0.48 * 2 -> 0.96 ............0
0.96 * 2 -> 1.92 ............1
0.92 * 2 -> 1.84 ............1
..........(循环) 当前是0.100011..........

所以你会发现 如果编译器不加以限制的话 12.56 的二进制小数 没完没了 因此 精度问题不就出现了

忠告: 每到底层 一定要脑子及时切换二进制 和 十进制场景!!!


OK,怎么解决这个double精度问题呢?

  • TOP1 醉翁之意不在酒

    如果是我刚才那道题那其实可以这样
    double res = 12.56 * 100 + 11.52 * 100   //嘿嘿 你有问题我有对策 巧妙转移问题 妙哉妙哉
    

    局限性: 如果你不清楚位数呢? 所以看看就好

  • TOP2 搬救兵

    更靠谱的做法是借助强大的BigDecimal 这才是实际开发中经常使用的方法

     BigDecimal b1 = new BigDecimal(Double.toString(12.56));//想想为啥不直接传递12.56给BigDecimal?  BigDecimal b2 = new BigDecimal(Double.toString(11.25));   System.out.println( b1.add(b2).doubleValue()); // 23.81
    

结语

当面试官问我的时候 有时候我曾一度怀疑自己是不是科班出身, 应了那句话 大学毕业后都还给老师了 呜呜呜… 是时候重新拾起了

对不起, 老师 我把知识还给您了 呜呜呜 ......面试杀手-double精度问题深入剖析 进制转换相关推荐

  1. 计算机基础知识 进制转换,计算机基础之进制转换详解

    进制转换是个老问题了,今天恰巧看见.我详细的去分析下它.留一笔吧 二进制的范围是(0-1), 不包含2 八进制的范围是(0-7) ,不包含8 十六进制的范围是(0-15) ,不包含16 先讲十进制-- ...

  2. 基础知识(一),ip地址详解、网关、DNS、进制转换、DOS命令、批处理、用户和组管理、telnet、RDP、NTFS、CIFS

    基础知识: 企业 >enterprise 专业 >profession 服务器 >server 客户端 >client 浏览器 >Browser B/S 架构:服务器对应 ...

  3. 单片机预备知识(电平、进制转换、字节、数据类型)

    参考:郭天祥十天带你精通51单片机 网址:https://www.bilibili.com/video/BV1DW411a7mz/?spm_id_from=333.788.videocard.0 目录 ...

  4. 计算机系统基础知识——进制转换(二进制、八进制、十进制、十六进制)

    前言:计算机系统中常用的进位数制有二进制.八进制.十进制.十六进制,对于任何一种进位数制,其表示的数都可以写成按权展开的 多项式. 1. 十进制与二进制的相互转换 1.1 十进制转二进制   十进制数 ...

  5. 编程基础知识(变简单的进制转换)

    编程基础--进制转换 前言    世界上有10种人,懂二进制的和不懂二进制的.    有同学会问,你说世界上有10种人,为啥只说了两个呢.这里的10可不一定是自然数十,也可能是二进制的一和零,不懂的同 ...

  6. 计算机基础知识系列·进制转换的简易方法

    本篇文章仅针对小白(刚刚学习计算机应用基础,计算机原理的小白),文章内容比较简单. 一.十进制数转换成二进制数. [例子1](1)十进制数字78转换二进制:(2)十进制数字374转换二进制. 答案:( ...

  7. 基础知识——进制 与 进制转换 (C++ 程序)

    目录 一.进制的定义 二.表示方法 1.当进制数 ≤ 10时 2.当进制数>10时 三.进制的计算 1.整数 2.小数 3.非十进制数 4.非十进制转十进制 四.十进制转非十进制数 1.整数部分 ...

  8. 【每日知识】进制转换:二进制、八进制、十六进制

    前言 在JavaScript中,我们可以分成两种类型: 基本类型: 复杂类型: 两种类型的区别是:存储位置不同. 1.基本类型 Undefined,Null,Number,Boolean,String ...

  9. 【基础知识】~ 进制转换、补码、格雷码、BCD码、独热码

    1. 进制转换 1.1 十进制 to 二进制 正整数转二进制:除二取余,然后倒序排列,高位补零. 负整数转二进制:先是将对应的正整数转换成二进制后,对二进制取反,然后对结果再加一. 小数转二进制:对小 ...

最新文章

  1. Netflix 开源用于 Spring Boot的 GraphQL 服务框架DGS
  2. win7下安装redies
  3. 使用C#实现Morse码的输出
  4. Linux 适用硬件平台/系统架构(i386 / i586 / i686 / x86 / x86_64)名词理解和区别
  5. ionic build Android错误记录 error in opening zip file
  6. Swift 性能相关
  7. MySQL | 数据库的六种约束、表的关系、三大范式
  8. 新版本vsphere支持最大单个vmdk超过2T,理论上支持最大62T
  9. 央视《新闻联播》正式入驻快手平台
  10. html之CSS设计(文本、边框、列表标签、display设置、内外边距)
  11. css3动画保持状态不变
  12. 关于投资收益和风险的例题(线性规划)
  13. Unity 官方标准资源下载(standard assets)2种方式
  14. python中日期转换,python中常用到的时间日期格式转换!
  15. 教程:使用Java以编程方式将PLT转换为PDF或图像
  16. NCM格式如何转换为Mp3(简单快速)
  17. 很有意境的语句[转]
  18. 【数据去噪】SG-多项式平滑算法
  19. androidstudio图片居中_Android imageView图片按比例缩放-Fun言
  20. 带pcb板的c语言实验报告,pcb实验报告.doc

热门文章

  1. 如何用python建模炒股_使用python 来实现炒股
  2. NotePad++不能添加HexEdit的原因
  3. Flutter Stack Align Positioned
  4. Java操作Kafka收发消息demo
  5. 香港服务器适合的网站,香港服务器优势是什么?
  6. Java中方法的重载详解
  7. Python爬虫-某某瓜网二手车数据
  8. Shel脚本学习—反引号、单引号、双引号区别与联系
  9. 2022山东养老产业展,中国智慧养老产业展览会,智能陪护展
  10. 2-3 实变函数之测度论