目录
用JAVA程序进行编译算出Float类型和Long类型的取值范围和16进制范围
写到这里突然发现通过使用Java程序算出的float范围和从书上看到的范围是不同的,所以,为什么呢?
通过强制转换来进行判断Float的取值范围比Long的取值范围要大
Float和Long的类型区别
Float类型
Float类型是一个浮点型的数据类型,同时也是单精度类型
Long类型
Long类型是一个整型的数据类型。
表格具体区别
类型名 | 数据类型 | 描述 | 大小/位数 | 取值范围 |
Float | 浮点型 | 单精度 | 32 | 3.4E-038---------3.4E+038(书上) |
Long | 整型 | 64 | -9223372036854775808----9223372036854775807 |
用JAVA程序进行编译算出Float类型和Long类型的取值范围和16进制范围
编写之前须知
函数须知
MAX_VALUE 英文含义 最大的值 这个函数表达的意思是最大的值的意思
MIN_VALUE 英文含义 最小的值 这个函数表达的意思是最小的值的意思
toHexString 以十六进制的无符号整数形式返回一个整数参数的字符串表示形式。
toUpperCase() 返回大小的字母
public static void main(String[] args) {
Scanner s= new Scanner(System.in);
String message="Hello world";
String x=message.toUpperCase();
System.out.println(x);
}
HELLO WORLD
使用JAVA计算Long的取值范围和十六进制的代码
代码段
public static void main(String[] args) {
System.out.print("Long的最大取值范围:");
System.out.println(Long.MAX_VALUE);
System.out.print("Long的最小取值范围:");
System.out.println(Long.MIN_VALUE);
System.out.print("Long的最大值的十六进制取值范围:");
String x = Long.toHexString(Long.MAX_VALUE).toUpperCase();
System.out.println(x);
System.out.print("Long的最小值的十六进制的取值范围:");
String y= Long.toHexString(Long.MIN_VALUE).toUpperCase();
System.out.println(y);
}
运行结果
Long的最大取值范围:9223372036854775807
Long的最小取值范围:-9223372036854775808
Long的最大值的十六进制取值范围:7FFFFFFFFFFFFFFF
Long的最小值的十六进制的取值范围:8000000000000000
为什么最大值的十六进制是7开头,而最小值是8开头
7的二进制是0111
8的二进制是1000
而正数还有一个在正数负数之间的0
所以负数的范围要比正数(不含0的情况下)的范围多1
最小值8000000000000000 这是个负数所以8000000000000000为补码
补码-1为反码7FFFFFFFFFFFFFFF
取反8000000000000000这个就为他的整数部分
使用JAVA计算Float的取值范围的代码
代码段
public static void main(String[] args) {
System.out.print("Float的最大取值范围:");
System.out.println(Float.MAX_VALUE);
System.out.print("Float的最小取值范围:");
System.out.println(Float.MIN_VALUE);
}
}
运行结果
Float的最大取值范围:3.4028235E38
Float的最小取值范围:1.4E-45
写到这里突然发现通过使用Java程序算出的float范围和从书上看到的范围是不同的,所以,为什么呢?
比较从书上得到的结果和通过程序算出来的结果进行对比
数据类型Float | 最小的取值范围 | 最大的取值范围 |
书上的 | 3.4E-038 | 3.4E+038 |
程序算出来的 | 1.4E-45 | 3.4028235E38 |
可以发现程序算出来的范围要比书上写的要多
这是为什么呢?
思考:为什么Float的实际范围要更大一些。
规格化表示
java中的浮点数采用的事IEEE Standard 754 Floating Point Numbers标准,该标准的规范可以参考//blog.csdn.net/treeroot/articles/94752.aspx.
float占用4个字节,和int是一样,也就是32bit.
第1个bit表示符号,0表示正数,1表示负数,这个很好理解,不用多管.
第2-9个bit表示指数,一共8为(可以表示0-255),这里的底数是2,为了同时表示正数和负数,这里要减去127的偏移量.这样的话范围就是(-127到128),另外全0和全1作为特殊处理,所以直接表示-126到127.
剩下的23位表示小数部分,这里23位表示了24位的数字,因为有一个默认的前导1(只有二进制才有这个特性).
后结果是:(-1)^(sign) * 1.f * 2^(exponent)
这里:sign是符号位,f是23bit的小数部分,exponent是指数部分,后表示范围是(因为正负数是对称的,这里只关心正数)
2^(-126) ~~ 2(1-2^(-24)) * 2^127
这个还不是float的取值范围,因为标准中还规定了非规格化表示法,另外还有一些特殊规定.
非规格化表示:
当指数部分全0而且小数部分不全0时表示的是非规格化的浮点数,因为这里默认没有前导1,而是0.
取值位0.f * 2^(-126),表示范围位 2^(-149)~~ (1-2^(-23)) * 2^(-126) 这里没有考虑符号.这里为什么是-126而不是-127? 如果是-127的话,那么表示为 2^(-127)-2^(-149),很显然2^(-127) ~~2^(-126) 就没法表示了.
其他特殊表示
1.当指数部分和小数部分全为0时,表示0值,有+0和-0之分(符号位决定),0x00000000表示正0,0x80000000表示负0.
2.指数部分全1,小数部分全0时,表示无穷大,有正无穷和负无穷,0x7f800000表示正无穷,0xff800000表示负无穷.
3.指数部分全1,小数部分不全0时,表示NaN,分为QNaN和SNaN,Java中都是NaN.
这篇文章给我的结论
这篇文章告诉了我们一个结论,那就是浮点数的范围大概是在:
2^(-149)~~(2-2^(-23))*2^127,也就是我用程序算出来的值。
比较二者(Float和Long)大小,
数据类型 | 最小取值范围 | 最大取值范围 |
Float | 2^(-149) | (2-2^(-23))*2^127 |
Long | -2^63 | 2^63 -1 |
Float的取值范围要大 | Float的取值范围要大 |
通过强制转换来进行判断Float的取值范围比Long的取值范围要大
如何转换
强制转换有一个特点就是大的取值范围转换为小的取值范围,自动转换不行的时候需要用到强制转换,所以当Float类型不能自动转换成Long类型但是可以通过强制转换可以,就证明Float类型比Long类型的取值范围大。
Float类型转换为Long类型代码
代码
public static void main(String[] args) {
float f = 1.0f;
long l = 1;
l=(long) f;
System.out.println(l);
}
结论
Float类型需要强制转换才能转换成浮点型
Long类型强制转换Float类型代码
代码
public static void main(String[] args) {
float f = 1.0f;
long l = 1;
f = l;
System.out.println(f);
}
结论
long类型可以自动转换成float类型
最终结论
Float的取值范围long的取值范围大