一、二进制
java中int型数据一般占用四个字节,32位,其中第32位为符号位,0表示正,1表示负。
int型max为:01111111 11111111 11111111 11111111=2147483647
int型min为:-10000000 00000000 00000000 00000000=-2147483648
负整数的二进制等于其正整数的二进制的反码再加1。例如上面,max值的反码就是min值的二进制,再加1就是-max值。
二、类型转换
(1)自动类型转换 。例:
byte a=1; int b=2; int c=a+b; 求得c=3;
这里计算过程中,编译器会自动的把占用内存小的转换为占用内存大的,即byte型会先转换成int型,在进行计算。
(2)强制类型转换。例:
int a=1; int b=2; byte c=a+b; //报错,cannot convert from int to byte
此时需要做强制类型转换,因为从4个字节的int型转换成一个字节的byte型会造成精度丢失等问题,所以编译器不会帮助自动类型转换,因为他不知道你需要的是精度还是类型。
方法是:byte c=(byte)(a+b); 即可。
三、运算符
例子一:
(1)byte a = 1; a = 2 + 3; 输出 a=5;没问题
(2)byte a = 1; byte b = 2; byte c = 3; a=b+c;//报错,cannot convert from int to byte
上面两个例子,其实值理论上是一样的,但是实际结果却差别那么大,原因在于a=2+3;这个过程中,运算的是两个常量,二常量在编译器眼里是可以直接断定值的。这时候他知道直接进行类型转换不会影响到值本身。但是在a=b+c;中这两个是变量,而变量在编译器眼里都是不确定的,很有可能发生精度丢失等问题,所以编译器不能帮你转换。不过从提示的错误来看,这里byte型进行运算时会优先转换成int型,输出结果也是int型,是不能直接赋值给byte的。
例子二:
(1)int a= Integer.MAX_VALUE ; int b=1; int c=a+b; 输出c=-2147483648
(2)int a= Integer.MAX_VALUE ; int b= Integer.MAX_VALUE; int c=a+b; 输出c=-2
从这两个例子中,可以看出来,最大值继续往上加,不是报错,而是变成负值。其实,前面提到过,第32位数是符号位,但是,在运算中,符号位是参与运算的,max值再加(可以对着二进制数运算一下),那第32位不就是进位了吗?从0变成1,1代表的就是负数呀。
例子三:
(1)int a= Integer.MIN_VALUE ; int b= Integer.MIN_VALUE; int c=a+b; 输出c=0
(2)int a= Integer.MIN_VALUE ; int b= Integer.MIAX_VALUE+2; int c=a+b; 输出c=1
从结果上看,挺奇怪的。原因是32位数在运算时,如果第32位数进位了,得到33位数,这时“+”运算会舍弃第33位数,只取后面32位,那第一个结果就是0了。(2)例子中,b的值应该是-max值,但是这里也一样,运算结果变成正的了,用二进制数运算也发现,最高位进位了,变成了0。但是,用简单的数学运算也会发现,max+min本来就等于-1,再加2等于1,不奇怪呀。但是计算机可不会给你来什么加法结合律,在进行c=a+b的运算前,b的值已经计算好了,就是等于-max。只是这时候进位后舍弃的做法,恰好得到了正确的值。其实也不是恰好,应该是当初设计的时候,已经把这些都考虑好了才设计出这种运算方式,只能说牛逼。