这在学习时。有一个例子是打印出无穷大与NaN 这两个数值。我在看完教程后。开始做。但是在打印正无穷大时打印出来的总是NAN的这个值。
请各位高手帮帮忙。帮我分析一下。我写的代码与老师写的是一样的。可是结果就是不一样。 ~~~I-I~~~
但我没有放弃一直在看这一节的课。下面是代码:
class lesson2
{
public static void main(String [] args)
{
System.out.println(Float.intBitsToFloat(0x7f800000)); //正无穷大
}
}
把Float.intBitsToFloat(0xff800000) (应是负无穷大)
结果总是NaN 这个结果。
请各位高手帮帮忙。帮我分析一下。我写的代码与老师写的是一样的。可是结果就是不一样。 ~~~I-I~~~
但我没有放弃一直在看这一节的课。下面是代码:
class lesson2
{
public static void main(String [] args)
{
System.out.println(Float.intBitsToFloat(0x7f800000)); //正无穷大
}
}
把Float.intBitsToFloat(0xff800000) (应是负无穷大)
结果总是NaN 这个结果。
public class B {
public static void main(String[] args) {
int n = 0x7f800000;
int s = ((n >> 31) == 0) ? 1 : -1;
int e = ((n >> 23) & 0xff);
int m = (e == 0) ? (n & 0x7fffff) << 1 : (n & 0x7fffff) | 0x800000;
/////////////////////
System.out.println("n = 0x" + Integer.toHexString(n));
System.out.println("three param : s=" + s + ";e=" + e + ";m=" + m);
System.out.println("float result =" + s * m * Math.pow(2, e - 150));
System.out.println("Float.MAX_VALUE =" + Float.MAX_VALUE);
}
}
//////////////////////////
n = 0x7f800000
three param : s=1;e=255;m=8388608
float result =3.4028236692093846E38
Float.MAX_VALUE =3.4028235E38
正好稍微超过float的表示范围
bit31是符号位,bit30-23是指数部分,bit22-bit0是尾数部分
比如:3.1415926
转换成二进制是11.00100100001111110110100110100010010110110000100101
只截取24位11.0010010000111111011010=110010010000111111011010*2^-22
-22+150=128
所以指数部分是128,10000000,符号位是0
整体就是
01000000010010010000111111011010
//----------------
按照这个思路,就得出
int s = ((n >> 31) == 0) ? 1 : -1;
int e = ((n >> 23) & 0xff);
int m = (e == 0) ? (n & 0x7fffff) << 1 : (n & 0x7fffff) | 0x800000;
n=s * m * Math.pow(2, e - 150)
150只是随意定的一个数值,把负指数转化为正的指数存储。
进一步的分析可知,这个150直接影响了float的表示范围
假设这个值为m,指数长度p=8,尾数长度q=23
则float的表示范围为[2^(-m+1),2^(2^p-1+q-m)]
令m=150,则范围为
(2^(-149),2^128)-->
(1.4012984643248170709237295832899e-45,3.4028236692093846346337460743177e+38)
根据这个分析,上限=3.4028236692093846346337460743177e+38,正好等于0x7f800000=0x1eP+128f,不过这是开区间,不包括端点,要减去最末位的一个单位,就是0x7f7fffff=0x1.fffffeP+127f=3.4028235E38。
所以你的数就超过范围了
看Float类的字段声明
public static final float MAX_VALUE = 3.4028235e+38f; // 0x1.fffffeP+127f
1 11111111 111 1111 11111111 11111111
////////////////////////////
这是float的存储区
前面1是符号位,接着11111111 是指数,最后111 1111 11111111 11111111是尾数
按照IEEE的规定,指数部分最大是254(为什么这样我也不明白),减去150作为实际的指数
最大可表示数可以看出就是这个01111111011111111111111111111111=0x7F7FFFFF
多谢你帮助我。
谢谢。