Java基本数值类型取值范围

本文深入解析Java中的Short、Integer、Long、Float、Double等基本类型的取值范围、内存占用及存储方式,涵盖符号位、指数位和尾数位的具体作用。

这里介绍一下Java的几个基本类型Short Integer Long Float Double,以及他们的取值范围,内存占用字节数,还有他们在内存中具体是如何存储的。

1.Short  2字节取值范围是-2^15 ~ (2^15-1) 

public final class Short extends Number implements Comparable<Short> {

    /**
     * A constant holding the minimum value a {@code short} can
     * have, -2<sup>15</sup>.
     */
    public static final short   MIN_VALUE = -32768;

    /**
     * A constant holding the maximum value a {@code short} can
     * have, 2<sup>15</sup>-1.
     */
    public static final short   MAX_VALUE = 32767;

    ...
}

可以从系统源码中看到MIN_VALUE = -32768 MAX_VALUE = 32767,

符号位(S):1bit 尾数位(M):15bit

由于short类型是2字节(16位)表示的,第1位为符号位,后面15位存储数值,所以取值范围是-2^15 ~ (2^15-1) 

2.Integer 4字节取值范围 -2^31 ~ (2^31 - 1)

public final class Integer extends Number implements Comparable<Integer> {
    /**
     * A constant holding the minimum value an {@code int} can
     * have, -2<sup>31</sup>.
     */
    @Native public static final int   MIN_VALUE = 0x80000000;

    /**
     * A constant holding the maximum value an {@code int} can
     * have, 2<sup>31</sup>-1.
     */
    @Native public static final int   MAX_VALUE = 0x7fffffff;
    
    ...
}

可以从源码中看到 MIN_VALUE = 0x80000000 MAX_VALUE = 0x7fffffff 这里需要注意的是前面有@Native注解,所以这里是实际在内存中存储的形式。可以看到最小值0x80000000反而比最大值0x7fffffff大1,这是为什么呢?写成2进制就可以理解

0x80000000 -> 1000 0000 0000 0000 0000 0000 0000 0000

0x7fffffff -> 0111 1111 1111 1111 1111 1111 1111 1111

带符号存储规定第一位表示符号位,0表示正数,1表示负数,所以最大值是0x7fffffff也就是(2^31 - 1)应该没什么问题了。然后负数采用补码的形式来存储,0x80000000第一位是1所以是负数,得到其绝对值就是2^31,所以0x80000000表示的值是-2^31。

Integer类型是由4字节表示的,取值范围就是-2^31 ~ (2^31 - 1)

3.Long 8字节取值范围-2^63 ~ (2^63 - 1)

public final class Long extends Number implements Comparable<Long> {
    /**
     * A constant holding the minimum value a {@code long} can
     * have, -2<sup>63</sup>.
     */
    @Native public static final long MIN_VALUE = 0x8000000000000000L;

    /**
     * A constant holding the maximum value a {@code long} can
     * have, 2<sup>63</sup>-1.
     */
    @Native public static final long MAX_VALUE = 0x7fffffffffffffffL;

    ...
}

Long与Short Integer都比较类似,都是用来表示整数的,唯一的区别就是长度不一样,并且它是由8字节表示的,所以直接可以类推出取值范围-2^63 ~ (2^63 - 1)

4.Float  正数取值范围2^-149 ~ (2-2^-23)*2^127

public final class Float extends Number implements Comparable<Float> {
    /**
     * A constant holding the positive infinity of type
     * {@code float}. It is equal to the value returned by
     * {@code Float.intBitsToFloat(0x7f800000)}.
     */
    public static final float POSITIVE_INFINITY = 1.0f / 0.0f;

    /**
     * A constant holding the negative infinity of type
     * {@code float}. It is equal to the value returned by
     * {@code Float.intBitsToFloat(0xff800000)}.
     */
    public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;

    /**
     * A constant holding a Not-a-Number (NaN) value of type
     * {@code float}.  It is equivalent to the value returned by
     * {@code Float.intBitsToFloat(0x7fc00000)}.
     */
    public static final float NaN = 0.0f / 0.0f;

    /**
     * A constant holding the largest positive finite value of type
     * {@code float}, (2-2<sup>-23</sup>)&middot;2<sup>127</sup>.
     * It is equal to the hexadecimal floating-point literal
     * {@code 0x1.fffffeP+127f} and also equal to
     * {@code Float.intBitsToFloat(0x7f7fffff)}.
     */
    public static final float MAX_VALUE = 0x1.fffffeP+127f; // 3.4028235e+38f

    /**
     * A constant holding the smallest positive normal value of type
     * {@code float}, 2<sup>-126</sup>.  It is equal to the
     * hexadecimal floating-point literal {@code 0x1.0p-126f} and also
     * equal to {@code Float.intBitsToFloat(0x00800000)}.
     *
     * @since 1.6
     */
    public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f

    /**
     * A constant holding the smallest positive nonzero value of type
     * {@code float}, 2<sup>-149</sup>. It is equal to the
     * hexadecimal floating-point literal {@code 0x0.000002P-126f}
     * and also equal to {@code Float.intBitsToFloat(0x1)}.
     */
    public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f
    
    ...
}

从上面源码可以看到,Float源码中,定义了很多特殊的值。不光只有最大值和最小值。

先介绍一下Float的存储格式4字节表示,32位

符号位(S):1bit指数位(E):8bit尾数位(M):23bit

符号位,0表示正数,1表示负数。

指数位,需要同时表示正指数和负指数,使用EXCESS形式表示。0111 1111表示0 ,1000 0000 表示1, 0111 1110表示-1。但是1111 1111和0000 0000有特殊用途,无法使用,所以指数的取值范围是0000 0001 ~ 1111 1110也就是-126 ~ 127。

尾数位,需要和指数位配合使用,把数值按标准表示,以1.1001 * 2^10(整数部分必须为1)这种形式表示。 比如,1.01就是表示为1.01*2^0,那么指数位(E)=0111 1111 尾数为(M)=0100 00...00(整数部分省略)

完整表示就是 0 01111111 0100 0000 0000 0000 0000 000

0.0011完整表示就是 0 01111100 1000 0000 0000 0000 0000 000

由于这个存储特性,所以就有几个特殊值需要存储:

正无穷大,POSITIVE_INFINITY = 1.0f / 0.0f 0x7f800000 ->   0 11111111 000...0000

负无穷大,NEGATIVE_INFINITY = -1.0f / 0.0f 0xff800000 -> 1 11111111 000...0000

NaN,0.0f / 0.0f 0x7fc00000 -> 0 11111111 100...0000

正最大值,MAX_VALUE = 0x7f7fffff -> 0 11111110 111...1111 (2-2^-23)*2^127

正最小值,MIN_NORMAL = 0x00800000 -> 0 00000001 000...0000 (1.0*2^-23)*2^-126 = 2^-149

5.Double

8字节表示,64位

符号位(S):1bit指数位(E):11bit尾数位(M):52bit

Double类型与Float相似,只不过指数位=11和尾数位=52有差别,其他存储没有差异。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值