都工做两年了,还不知道浮点数如何转二进制?

image


来吧,坐下聊

先前在前文 《老大说:谁要再用double定义商品金额,就本身收拾东西走》 中就已经痛彻心扉地聊过:工具

在处理诸如 订单交易货币计算、以及 商品金额慎用浮点数( double/ float)去定义变量,不然可能会遇到各类奇葩的问题,具体示例在那篇文章中都详细展现过。

当时写那篇文章的时候,我觉得你们对于小数转二进制的换算早已了然于胸,因此也就没有给出具体的换算过程。结果文章发出来后,私信里一票小伙伴反馈说,文中那些小数转二进制的例子究竟是怎么换算出来的,最好详解一下。编码

image

得嘞,这不就来了嘛!spa

顺带聊一句,看来《计组原理》或者说《计算机系统》这门课有必要小规模回炉重造一下了(滑稽)。3d

不过实不相瞒,CRUD、复制粘贴、调接口、写业务代码久了,计算机基础确实好多都忘了...我也有深有同感!code


浮点数在计算机中是如何表示的?

学过 《计算机组成原理》 或者相似 《计算机系统》 这些课程的小伙伴们应该都知道,浮点数在计算机中的存储方式遵循IEEE 754 浮点数计数标准,能够表示为:blog

image

采用尾数 + 阶码的编码方式,更通俗一点说,就是相似于数学课本上所学的科学计数法表示方式:有效数字 + 指数位接口

所以,只要给出:符号(S)阶码部分(E)尾数部分(M) 这三个维度的信息,一个浮点数的表示就彻底肯定下来了,因此floatdouble这两种类型的浮点数在计算机中的存储结构就表示成下图所示这个样子:rem

image

image

一、符号部分(S)数学

0-正 1-负it

二、阶码部分(E)(指数部分)

  • 对于float型浮点数,指数部分8位,考虑可正可负,所以能够表示的指数范围为-127 ~ 128
  • 对于double型浮点数,指数部分11位,考虑可正可负,所以能够表示的指数范围为-1023 ~ 1024

三、尾数部分(M)

浮点数的精度是由尾数的位数来决定的:

  • 对于float型浮点数,尾数部分23位,换算成十进制就是 2^23=8388608,因此十进制精度只有6 ~ 7位;
  • 对于double型浮点数,尾数部分52位,换算成十进制就是 2^52 = 4503599627370496,因此十进制精度只有15 ~ 16

因此,浮点数交给计算机存储的时候,可能会有精度丢失问题!!!所以使用时须要格外当心,若是真由于这一块出了bug,定位问题仍是很是艰难的,因此预防工做要作好。


进制转换计算案例

上面说的是IEEE标准规定的内容,属于理论规约。那一个小数到底要怎么换算成二进制呢?咱们得拿实际例子来解释。

先来个简单的例子

好比:把十进制小数0.875转换成二进制,具体怎么操做?

能够分几大步走:

一、以小数点为界,拆分

二、整数部分转换

整数转二进制我想你们应该都熟悉,使用:除2取余法 便可。而这里的0.875整数部分为0,无需操做。

三、小数部分转换

小数部分的转换不一样于整数部分,采用的是 “乘2取整法” ,图示一下就明白了:

image

四、合并结果

整数部分 + 小数部分,最终获得二进制结果为0.111

因此该结果按照上一节所述的尾数 + 阶码的计算机计数方式,则能够表示为:

image

因此对应可得:

  • 符号位0
  • 阶码(E)部分:若以float为例,应为 127 +(-1)= 126,所以二进制表示为:01111110
  • 尾数部分(M):若以float为例,应为23位,所以尾部补齐后为11000000000000000000000

所以最终的总结果为(以32位精度float表示):

00111111011000000000000000000000

再来个复杂点例子

再好比:把十进制小数6.36转换成二进制,具体怎么操做?

但凡能用图示,我就不想写文字,因此用一张图就能够解释得明明白白:

image

整数部分 + 小数部分,所以最终获得的结果二进制结果为110.01011100...

仍是按照上一节所述的尾数 + 阶码的计算机计数方式,则能够表示为:

image

因此对应可得:

  • 符号位:0
  • 阶码(E)部分:若以float为例,应为 127 +(2)= 129,所以二进制表示为:10000001
  • 尾数部分(M)1001011100...,其实它自己无限不循环,但若以float型精度来截取23位,则能够表示为10010111000010100011111

所以最终的总结果为(以32位精度float表示):

01000000110010111000010100011111

因此像这种无限位数的尾数状况,用计算机存储产生截取是必然的,一定会有必定的精度损失!因此这也从根本上解释了为何float或者double这种类型数据使用时的风险性,所以必需要结合实际业务理性考量。


神器加持

你们若是对上面的计算结果不放心,或者想检查手动换算的结果是否正确,也有直接的这种二进制转换工具站,典型的好比binaryconvert

image

不想手动换算的,直接去上面输入,转换一下便可获得结果,并且能够进制互换,使用很是方便。


回味

有时候回顾一下基础真的蛮有意思的,好比写这篇文章时,虽然是很基础的东西,可是表达出来的过程仍是挺有趣的,尤为是画图展示的过程,但愿能和小伙伴们共勉。

相关文章
相关标签/搜索