JAVA中整数类型数据溢出问题研究

来源:互联网 发布:java封装snmp协议 编辑:程序博客网 时间:2024/06/06 23:31

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 qq1013985957 * */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));}}
测试结果


0 0
原创粉丝点击