Java中的数值类型都是有符号类型,最高位表示符号位。这里我们以byte类型为例,探讨整型的数据溢出问题。
基本数据类型 对应的包装类 所占bit位 取值范围
byte Byte 8 -2^7 ~ 2^7-1
short Short 16 -2^15 ~ 2^15-1
int Integer 32 -2^31 ~ 2^31-1
long Long 64 -2^63 ~ 2^63-1
为啥取值范围是这样呢?下面我们慢慢来看下。
package com.lcx.datatype;
/**
*
* @author
*
*/
public class ByteTest {
public static void main(String[] args) {
bypeM();
}
public static void bypeM(){
/**
* Java中的数值类型都是有符号类型,最高位表示符号位。
* 这里我们以byte类型为例,探讨数据溢出问题
* byte类型 占一个字节8个bit位,所以能表示的数值形式(注意不是数值范围,因为第一位是符号位)是 0 000 0000 ~ 1 111 1111 也就是可以表示2^8-1+1 = 256个数字
* 由于第一位是符号位,那么
* 正数的范围是 0 000 0000 ~ 0 111 1111 --> 0 ~ 127
* 负数的范围是 1 000 0000 ~ 1 111 1111 -->-128~-1
* 总的范围是 1 000 0000 ~ 0 111 1111 -->-128 ~ 127(-2^7 ~ 2^7-1)
* 同理 short、int、long 都是这样
* 计算机中,负数使用补码形式表示,正数的原码、反码、补码都相同,负数的反码是符号位1除外其余取反,负数的补码 = 反码+1
* 1 000 0001 -1的原码
* 1 111 1110 -1的反码
* 1 111 1111 -1的补码
* 通过这种方式 我们可以反推 1 111 1111 表示 -1
* 这里的-128的补码形式有点特殊,可以理解为数值包含符号位了,不知道下面这种解释对不对。
* 1 1000 0000 -128的原码
* 1 0111 1111 -128的反码
* 1 1000 0000 -128的补码
* 由于byte只能有8bit位,现在占9bit位, 多的那一位移除掉保留后面8位,-128的补码 为 1000 0000
*
* 模拟数据溢出
* Byte.MAX_VALUE = 0 111 1111 = 127,Byte.MAX_VALUE+1 = 1 000 0000 = -128,Byte.MAX_VALUE+2 = 1 000 0001(-->反码1 000 0000-->原码1 111 1111) = -127
* Byte.MIN_VALUE = 1 000 0000 =-128,Byte.MIN_VALUE-1 = 0 111 1111 = 127,Byte.MIN_VALUE-2 = 0 111 1110 = 126
*/
Byte b_max_plus_1 = (byte) (Byte.MAX_VALUE + 1);//最大值+1 数据溢出到最小值
Byte b_max_plus_2 = (byte) (Byte.MAX_VALUE + 2);
Byte b_min_minus_1 = (byte) (Byte.MIN_VALUE - 1);//最小值-1 数据溢出到最大值
Byte b_min_minus_2 = (byte) (Byte.MIN_VALUE - 2);
System.out.println("Byte.BYTES="+Byte.BYTES);
System.out.println("Byte.MAX_VALUE="+Byte.MAX_VALUE);
System.out.println("Byte.MIN_VALUE="+Byte.MIN_VALUE);
System.out.println("b_max_plus_1="+b_max_plus_1+","+"b_max_plus_2="+b_max_plus_2);
System.out.println("b_min_minus_1="+b_min_minus_1+","+"b_min_minus_2="+b_min_minus_2);
//Byte没有打印二进制的工具函数,Integer有打印二进制的工具函数
System.out.println("Byte.MAX_VALUE的二进制 = "+Integer.toBinaryString(Byte.MAX_VALUE));//前面为0的bit位没有打印
System.out.println("Byte.MIN_VALUE的二进制 = "+Integer.toBinaryString(Byte.MIN_VALUE));
System.out.println("Integer.MAX_VALUE的二进制 = "+Integer.toBinaryString(Integer.MAX_VALUE));//第一位 符号位0 没有打印
System.out.println("Integer.MIN_VALUE的二进制 = "+Integer.toBinaryString(Integer.MIN_VALUE));
}
}
测试结果