int i = Integer.MAX_VALUE;//2147483647 float f = 2.1474836E9f;//单步跟踪下, f 的值是 2.14748365E9
int j = (int)f; boolean bi = i == j;
System.out.println("bi= "+bi);上面这段代码执行后,bi将等于 true,是什么原因呢? 单步跟踪下, f 的值是 2.14748365E9,明显与程序中不一样。搜索了一下,也没找到有关float 和double在java中存储的清楚详细的说明。谁有这个的详细说明?(最好画个图)
int j = (int)f; boolean bi = i == j;
System.out.println("bi= "+bi);上面这段代码执行后,bi将等于 true,是什么原因呢? 单步跟踪下, f 的值是 2.14748365E9,明显与程序中不一样。搜索了一下,也没找到有关float 和double在java中存储的清楚详细的说明。谁有这个的详细说明?(最好画个图)
解决方案 »
- java的动态数组和类集有什么区别
- 关于设计模式的问题请教
- JFrame上添加JPanel出错 请各位高手看看
- 小弟请教一个Enumeration和enum的问题
- 现在的java application支持音频播放不
- 把eclipse左边的工程窗口弄没了。。。
- <sql:query>怎么实现类似first,last,next功能?<c:forEach>好象要历遍
- 有问题,希望大家帮忙。。
- 本人有C/C++,DELPHI,VB的基础,想改学Java,该从何做起?
- this的用法
- 引入import sun.misc.BASE64Decoder和import sun.misc.BASE64Encoder的问题
- 急!如何用正则表达式提取字符串中如下内容?
这里不详细解释,LZ可查阅相关资料
有几个知识点:
1.计算机中浮点数的基数是2.
2.指数部分有偏移量(float为127, double为1023)
3.规格化的表示小数点左边一定为1.(二进制数)
4.float类型 符号位占1位,指数部分占8位,尾数占23位(因为规格化表示,小数点左边一定为1,所以实际有24位精度)
5.double类型 符号位占1位,指数部分占11位,尾数占52位(因为规格化表示,小数点左边一定为1,所以实际有53位精度)看一个例子float 0.6吧:
第一步,把十进制转2进制:
0.6的二进制表示(乘2取整,顺序表示):
.1001 1001 1001 1001 1001 1001 1001 ... 无限循环下去。第二步,计算尾数部分:
把.1001 1001 1001 1001 1001 1001 1001 ...规格化表示(小数点移到第一个非0书右边)就是:
1.001 1001 1001 1001 1001 1001 1001 ...,右移了1位。
由于规格化表示的数小数点左边一定为1,把这个1舍弃,并保留float尾数能表示的23位,最终尾数部分是:
001 1001 1001 1001 1001 1001第三步,计算指数部分:
由于计算尾数时右移了1位,相当于乘以2的负1次,所以指数为-1,加上float偏移量127,最后指数为126,
二进制表示为 0111 1110第四步,符号部分:
0.6为正数,符号位为0最终0.6在计算机中的表示就是: 符号位 指数 尾数
0 0111 1110 001 1001 1001 1001 1001 1001
--------------------------------------------------------------
我们再从这个2进制来计算10进制数:(2的指数次 * 尾数)
符号位0--> 为正
指数 0111 1110:为126, 减去偏移量127,结果为-1.
尾数 001 1001 1001 1001 1001 1001: 规格化的时候小数点左边人掉了一个1,现在加上:
1.001 1001 1001 1001 1001 1001,转为10进制就是:
1*2^0 + 1*2^-3 + 1*2^-4 + .....= 1.19999992847442626953125
1.19999992847442626953125 * 2^-1 = 0.599999964237213134765625
所以最终结果是一个无限接近于0.6而不能精确表示0.6
结贴,散分