• 处理精度丢之-浮点数在计算机中是如何存储的


    平时项目开发中经常会遇到一些精度丢失的问题,像老生常谈的0.1 + 0.2 !== 0.3,只知道是计算机的二进制实现和位数限制,有些数无法有限表示,但却没认真去亲自检测过。今天心情好,来测试一把。

    在此之前,我们先来复习一下还给老师的知识点

    二进制转十进制

    十进制转二进制:

        整数:

       

    小数:

    知道是怎么算就阔以了,快速转换进制,工具送上:https://tool.oschina.net/hexconvert/

    在计算机中,我们存储一个数的存储结构由三小块组成,对应 符号位 、指数位、尾数位

    符号位

    简单清晰,占一位: 1代表负数, 0 代表正数

    指数位

    浮点数可分为单精度类型and双进度类型,单精度指数位: 占8位, 双进度指数位: 占11位。

    对前端来说,我们知道JavaScript 存储小数和其它语言如 Java 和 Python 都不同,JavaScript 中所有数字包括整数和小数都只有一种类型 即 Number类型,是以64位双精度浮点数存储所有Number类型值,所以指数位占11位。

    关于指数位的计算:

    • 计算机对于整数的存储只需要转换成对应的进制。相比于小数,小数点的位置无法确定,小数点后面的位数也无法确定。所以提出借助科学计数法解决,例如:11011.1 科学计数法转化为:1.10111 * 24,这样小数点的位置就确定下来了
    • 偏移量: 2k - 1,  k代表所占位数,像单精度占8位,双精度占11位,所以单精度指数偏移量为127, 双精度指数偏移量为1023
    • 指数位 = 偏移量 + 指数

    以双精度来举例:

    11011.1 科学计数法转化为:1.10111 * 24,因为是双精度,所以偏移量为1023, 指数为4, 所以指数位的值为1027(此时得到的值位十进制,需要转换成计算机识别的二进制)

    再转化为二进制: 1000 0000 011 (tips: 转化的二进制不足位数时,记得补0,这里刚好是11位,不用补)

    尾数位

    • 单精度占23位, 双精度占52位
    • 取转换为科学技术发后小数点后面的值就完事了(下方案例送上)

    案例补充:

    0.1

    转化为二进制:

    0.0001100110011001100110011001100110011001100110011001101

    转科学计数法:

    1.100110011001100110011001100110011001100110011001101 * 2-4

    转实际存储:

    正数: 0

    指数位:1023 + (- 4 ) = 1019 转 二进制: 1111 1110 11 --》 指数位为11位,补0得到:01111111011

    尾数位:1001100110011001100110011001100110011001100110011010

    结果:0 01111111011 1001100110011001100110011001100110011001100110011010

    tip: 指数位从前往后补0;尾数位从后往前补0;

    27.5

    转二进制:

    11011.1

    转科学技术法:

    1.10111 * 24

    转实际存储:

    正数: 0

    指数位:1023 + 4 = 1027 转二进制:1000 0000 011

    尾数位:10111

    结果:0 1000 0000 011 10111000000000


    机器数0 1000 0000 011 10111000000000 转10进制

    取符号位: 0为正数

    取指数位:1000 0000 011 转10进制:1027,得到指数: 1027 - 1023 = 4

    取尾数位:10111000000000

    转科学技术法表示:1.10111000000000 * 24

    转二进制:11011.1

    转十进制:27.5

    Next: 处理精度丢失之-如何解决

  • 相关阅读:
    Eclipse导入Ant项目
    Eclipse修改默认包路径的起始文件夹
    Java中DAO/DTO/PO/VO/BO/QO/POJO
    FreeMarker与Spring MVC 4集合的HelloWorld示例
    FreeMarker与Spring MVC 4结合错误:Caused by: java.lang.NoClassDefFoundError: org/springframework/ui/freemarker/FreeMarkerConfiguration
    FreeMarker与Servlet结合示例
    FreeMarker-简单示例
    Java模板引擎-FreeMarker
    SiteMesh2-sitemesh.xml的其它映射器的用法
    SiteMesh2-sitemesh.xml的ParameterDecoratorMapper映射器的用法
  • 原文地址:https://www.cnblogs.com/Tiboo/p/13702637.html
Copyright © 2020-2023  润新知