快乐随行

导航

Java中的基本数据类型int及数据溢出

1. 概述

Java语言内置了八种基本数据类型:六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。

其中int 数据类型是++32位++、++有符号++的以++二进制补码++表示的整数

  • 最小值是 -2,147,483,648(-2^31);
  • 最大值是 2,147,483,647(2^31 - 1);
  • 一般的整型变量默认为 int 类型;
  • int的默认值是 0
public class Test {  
    public static void main(String[] args) {
        System.out.println("二进制长度:" + Integer.SIZE); 
        System.out.println("最小值Integer.MIN_VALUE = " + Integer.MIN_VALUE); 
        System.out.println("最大值Integer.MAX_VALUE = " + Integer.MAX_VALUE);  
    }
}

输出结果:

二进制长度:32
最小值Integer.MIN_VALUE = -2147483648
最大值Integer.MAX_VALUE = 2147483647

2. 补码

Java里的int是有符号的,二进制系统是通过补码来保存数据的,最高位为1的数字用来表示负数,而最高位为0的数字表示非负数。

正数补码等于原码,负数的补码等于其绝对值的反码+1。例如:-1的补码就是绝对值1的反码(按位取反) 再+1。计算方式如下:

  0000 0000 0000 0000 0000 0000 0000 0001      => 1的二进制
  1111 1111 1111 1111 1111 1111 1111 1110      => 1的反码
+ 0000 0000 0000 0000 0000 0000 0000 0001
-----------------------------------------
  1111 1111 1111 1111 1111 1111 1111 1111      => -1的补码

常见整数对应的补码:

1000 0000 0000 0000 0000 0000 0000 0000 => -2147483648
1111 1111 1111 1111 1111 1111 1111 1111 => -1
0000 0000 0000 0000 0000 0000 0000 0000 => 0
0000 0000 0000 0000 0000 0000 0000 0001 => 1
0111 1111 1111 1111 1111 1111 1111 1111 => 2147483647

例:获取整数二进制

public class Test {
    public static void main(String[] args) {
        int[] arrayInt = new int[] {Integer.MAX_VALUE, 0, 1, -1, Integer.MIN_VALUE};
        for (int x : arrayInt) {
            String binaryString = Integer.toBinaryString(x);
            int length = Integer.SIZE;
            while(binaryString.length() < length){
                // 在不足的位数前加“0”
                binaryString = "0" + binaryString;
            }
            // 为了方便查看,每4位插入分割符
            int m = binaryString.length()/4 - 1;
            StringBuffer stringBuffer = new StringBuffer(binaryString);
            for (int i = m; i > 0; i--) {
                int j = 4 * i;
                stringBuffer.insert(j,' ');
            }
            System.out.printf("%,14d", x);
            System.out.print(" 对应的二进制为:");
            System.out.printf("%s%n", stringBuffer.toString());

        }
    }
}

输出结果:

 2,147,483,647 对应的二进制为:0111 1111 1111 1111 1111 1111 1111 1111
             0 对应的二进制为:0000 0000 0000 0000 0000 0000 0000 0000
             1 对应的二进制为:0000 0000 0000 0000 0000 0000 0000 0001
            -1 对应的二进制为:1111 1111 1111 1111 1111 1111 1111 1111
-2,147,483,648 对应的二进制为:1000 0000 0000 0000 0000 0000 0000 0000

3. 数据溢出

首先,基本的数据类型(long,int,short,byte,char,float,double)都有自己能够保存的数据范围。

数据溢出

当某一种类型的数值已经达到了此类型能够保存的最大值之后,再继续扩大,或者达到了最小值后再继续缩小,就会出现数据溢出问题。而溢出不会出错,却会得到一个意外的结果:

public class MyDemo{
	public static void main(String args []){
		int a = Integer.MAX_VALUE;//定义一个int型变量a的值为int型能够保存的最高值
		System.out.println(a + 1);
		int b = Integer.MIN_VALUE;//定义一个int型变量a的值为int型能够保存的最小值
		System.out.println(b - 1);
	}
}

输出结果:

-2147483648
2147483647

下面解释出现这种情况的原因:

  0111 1111 1111 1111 1111 1111 1111 1111      => 2147483647的补码
+ 0000 0000 0000 0000 0000 0000 0000 0001
-----------------------------------------
  1000 0000 0000 0000 0000 0000 0000 0000      => -2147483648的补码
  • 最轻微的上溢是 INT_MAX + 1 :结果是 INT_MIN。
  • 最严重的上溢是 INT_MAX + INT_MAX :结果是 -2。
  • 最轻微的下溢是 INT_MIN - 1 :结果是 INT_MAX。
  • 最严重的下溢是 INT_MIN + INT_MIN :结果是 0。

最大值加1时,反而变成范围的最小值,加2变成范围的次小值,这种情况可以想象出一个循环。

数据溢出的解决办法:

我们已经知道,在整型中,能够保存的数值范围最大的是long型;在浮点型中,能够保存的数值范围最大的是double型。所以在遇到数据溢出问题时,我们可以先把能够保存的数值范围小的类型转换为范围大的类型,再进行运算。

例:

public class Test{
	public static void main(String args []){
	    //定义一个int型的最大值
		int x = Integer.MAX_VALUE;
		System.out.println((long)x+2);
	}
}

输出结果是:2147483649

posted on 2021-02-02 11:47  快乐随行  阅读(755)  评论(0编辑  收藏  举报