12.0f-11.9f=0.10000038,为什么?浮点型数据在内存中的存储问题

要想解决这个问题,我们需要先来了解一下float在内存中的存储

一、浮点型在内存中的存储

>>Java中float在内存中的存储占4个字节,float的32位二进制结构如下:

313029-2322-0
实数符号位指数符号位指数位有效数位

 

 

 

有效位数位为24位,其中一个是实数符号位。

>>doublie型在内存中占8个字节,64个bit位,double的64位二进制结构如下:

636261-5251-0
实数符号位指数符号位指数位有效数位

 

 

 

有效位数位为52位,其中一个是实数符号位。

二、将一个float型转化为内存存储格式

(以11.9为例)

<1>将这个实数化为二进制格式,注意实数的整数部分和小数部分的二进制转化;

        参考https://blog.csdn.net/sophie1314/article/details/84287948

             (11.9转化为二进制:1011.1110011001100....)

<2>将这个二进制格式实数的小数左移或右移n位,直到小数点移动到第一个有效数字的右边

            (则1011.1110011001100....变为1.0111110011001100...)

<3>有效数位:从小数点右边第一位开始,数出23位有效数字放到第22-0位;(产生误差)

            (1.0111110011001100....右边取23位,为0111 1100 1100 1100 1100 110)

<4>实数符号位:如果实数的,则在第31位放入0,否则放入1;

             (11.9是正的,所以放0)

<5>指数符号位:如果n左移得到的,则表示n是正的,在30位放入1,否则放入0;

              (左移三位,为正,放入1)

<6>指数位:如果n是左移得到的,则n-1之后化为二进制,并在左边加“0”补足7位;如果是右移得到的或者n=0,则化为二进制左边加“0”补足7位,然后再各位求反,然后再放入29-23位。

               (左移得到的,3-1=2,0000010)

所以,最终得到11.9在内存中存储的是0 1 0000010 01111100110011001100110

三、将一个内存存储格式的float二进制转化为十进制

<1>取出后面23位,在前面加“1.”,得到24位有效位数(如果十进制化二进制时产生误差,那么二进制化十进制也会有误差)

<2>从左数取第一位,0表示正数,1表示负数

<3>从左数取第二位,1表示指数为正,0表示指数为负

<4>若第二位数为1,则从左数第3位到第9位,化为十进制加1得到n,24位有效位数小数点右移n位,化为十进制即得到最终结果;若第二位数位0,则先求反然后再化为十进制数为n,24位有效位数左移n位小数点,化为十进制即得到最终结果。

四、浮点型的减法运算

<1>检查0操作数:如果浮点数中有一个为0,即可得知运算结果而没有必要再进行有序的一些列操作。 

<2>比较界码大小并完成对阶,看两数的指数位是否相同,即小数点位置是否对齐。若两数指数位相同,表示小数点是对齐的,就可以进行尾数的加减运算。反之,若两数阶码不同,表示小数点位置没有对齐,此时必须通过进行尾数的移位,使两数的阶码相同,这个过程叫做对阶 。

<3>有效位数进行加减法运算

对阶完毕后就可以对有效数位求和。不论是加法运算还是减法运算,都按加法进行操作,其方法与定点加减运算完全一样。

<4> 结果规格化并进行舍入处理。

五、计算12.0f-11.9f

12.0f 的内存存储格式为:    0 1 0000010 10000000000000000000000     

11.9f 的内存存储格式为:     0 1 0000010 011 11100110011001100110

    可见两数的指数位完全相同,只要对有效数位进行减法即可。

12.0f-11.9f   结果:         0 1 0000010 00000011001100110011010

将结果还原为十进制为: 0.000 11001100110011010= 0.10000038

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值