浮点型精度

今天一同事发现,往数据库插入一字段值为400000.18,库中变成400000.19,字段为float类型。(以下讨论皆针对单精度浮点)

 

找了下资料,浮点型运算基本按照IEEE-754格式标准,FLOAT是由4个字节(32位)组成:

SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

S: 第一位:表示浮点数正负,1为负数,0为正数
E: 指数加上127后的值的二进制数
M: 24-bit的底数(由于符号位已经由S标识了,只存储23-bit)

 

按照上图,浮点型最多只能精确2^23内的整数,但由于IEEE754标准对底数格式作了规范:即二进制的1.xxxxx,因此底数小数点左面部分总是1,在这里,为了提高精度,把1省略了,因此实际上最多能精确到2^24-1(即16777215)内的整数。由此可见,整数最大可保证精度为7位。

 

至于带小数的处理,由于小数位与整数位是分开计算,而且由于小数位独特的转二进制方法,可能存在无限循环,决定了浮点的小数位无法做到100%精确,使带小数的浮点精度更低。直到现在,我还不解为何转二进制采用乘2取整如此独特的方法,正是因为这种方法导致小数位无法像整数位一般精确。

 

结论:单精度浮点最大可保证精度是7位(xxxxx.xx),JAVA中的浮点型,如果需要7位数值以上的精确度,就换成BigDecimal(推荐)或double型(52bit底数,15位精确度),在MYSQL中则推荐采用DECIMAL(x,y)。

 

标准参考:http://en.wikipedia.org/wiki/IEEE_754-2008

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值