加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

java中long到float的自动转换引发的血案

(2014-03-25 16:22:58)
标签:

java

float

long

it

吐槽一句:论文快写吐啦~~ 闲的看了一会java资料,然后就悲剧了.....

事情是这样的,都知道在java中long为8字节64位,float是4字节32位,然后看到long到float的自动转换就有点confuse,一个容器大的转到一个容器小的里,可以?!
答案明显是可以的,然后我就搜了一下,原以为几个字可以解释清楚的东西,整整翻了很多资料(堪比论文吐血状态)。不废话了,开始解释:
首先能自动转换,原因在于float的数值表示范围大于long的表示范围,long是有符号整型,范围在-2的63次方到2的63次方-1之间,至于float的范围叙述起来比较麻烦,因此自己写个程序看看吧。重点在于float32位如何能表示比long64位还大的数,原因就是位数的含义(有点废话)

float的32位,可以分为三段来看,第一段占第一位,表示正负;第二段第2-9位表示指数;第三段第10-32位表示尾数
接下来看一个小数在float中是怎样存储的。
比如120.5,二进制表示为1110110.1(至于小数部分的二进制表示,简单说一下,就是*2,大于零为1,然后减去1再乘2重复,小于0写0,然后再乘2重复),接下来将这个二进制表示的数用科学计数法表示成1.1101101*2E6,
暂时不考虑极端情况,所有的数都可以表示成这种1.***2Ee的形式,这里将1舍去(重点来了),
小数点后面的1101101作为尾数存入尾数区域(因为float尾数区域为23位,所以有可能产生精度损失)。
由于舍弃了1(变为默认),尾数区域的23位长度可以表示24位的精度。尾数部分介绍完毕,开始考虑指数部分。
float,指数区域为8位,范围0-255之间。由于指数可正可负所以采用移位存储方法,元数据为127,这样表示范围扩展到实际为0-255,将小数科学计数法表示中的指数+127存在float的指数位置,在例子里就是6+127=133,二进制表示为10000101,将这个二进制存储在指数位置
第一位的符号位不多讲,至此120.5作为float类型值在计算机内存储(不是计算机内部存储,因为还要涉及大端小端问题)为
0  10000101  110110100000000000000
介绍完毕
由此可以知道float类型的值表示为  1.尾数区域*2E(指数区域-127),范围比long类型要大,可以实现long到float的自动转换,也就是区间问题

在这里要说一下,float类型值范围比较大,但是不代表区间内的所有值都一定能精确表示,事实上0.3就不能精确表示,所以不管是long到float的自动转换还是float到long的强制类型转换都有可能丢失精度

接下来说一下float类型值在计算机内实际存储
由于intel cpu的架构是LITTLE-ENDIAN它是按字节倒序存储的
float
共计32位,折合4字节
由最高到最低位分别是第 31、30、29、……、0位
31位是符号位,1表示该数为负,0反之。
30-23位,一共8位是指数位。
22-0位,一共23 位是尾数位。
每8位分为一组,分成4组,分别是A组、B组、C组、D组。
每一组是一个字节,在内存中逆序存储为dcba

写完了,继续扑进论文里
ps:以后还是要多想想怎么来的,而不是结论

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有