黑马程序员技术交流社区
标题:
数据溢出
[打印本页]
作者:
王梁星
时间:
2012-11-9 20:57
标题:
数据溢出
本帖最后由 王梁星 于 2012-11-9 22:16 编辑
一个很简单很随意的例子:
class PrecisionIntToByte{
public static void main(String[] args){
int i=177;
byte b=(byte)i;
System.out.println(b);
}
}
复制代码
结果是,b=-79
为什么是-79。
我想到byte范围是:-128~127,那么溢出177-127=50.50的二进制是:110010.
然后呢,怎么考虑?
我写的证明,但还是不甚明了:
class PrecisionIntToByte{
public static void main(String[] args){
int i=-179;
System.out.println(i+" binary is "+Integer.toBinaryString(i));
byte b=(byte)i;
System.out.println(b);
System.out.println(b+" integer is "+Integer.toBinaryString(b));
}
}
复制代码
运行结果是:
-179 binary is 11111111111111111111111101001101
77
77 integer is 1001101
如二楼王振同志说的:
byte占一个字节,共8个二进制位。而-179对应的二进制超出了八位。所以,byte b=(byte)i;的结果取-179对应二进制的最后八位01001101,0忽略,写作1001101,己十进制的77。
若i是整数,同理
作者:
赵保磊
时间:
2012-11-9 21:23
占个沙发 {:soso_e130:}
作者:
王振
时间:
2012-11-9 21:34
本帖最后由 王振 于 2012-11-9 21:36 编辑
所谓溢出不是简单的拿范围去相减的,实际情况是这样的:
原本i是个int类型的数值,占4个字节,共32位。
177在内存中的二进制表示的最后8位是10110001,前面的24位都是0。
当你强制转换的时候,需要转换成byte类型。
byte类型只占1个字节,共8位。
JVM的处理方法是将前面24位全部去掉,只留最后8位,也就是10110001.
这样貌似和之前的数没有区别,但是还有一个知识点,就是当位数补全时,最前面一位是符号位,若为0,代表是正数,若为1,代表是负数。
因此,现在对于byte类型来说,8位已经满了,它会把第一位当成是符号位,因为是1,所以是负数。
然后你用二进制转换十进制的规则计算就可以了。
负数转十进制:首先减1,得到10110000.
然后取反,得到01001111;
将01001111转换为十进制,为79;
随后前面加上符号,得到-79,。
作者:
王梁星
时间:
2012-11-9 22:05
本帖最后由 王梁星 于 2012-11-9 22:07 编辑
王振 发表于 2012-11-9 21:34
所谓溢出不是简单的拿范围去相减的,实际情况是这样的:
原本i是个int类型的数值,占4个字节,共32位。
177 ...
本句[对于byte类型来说,8位已经满了,它会把第一位当成是符号位,因为是1,所以是负数。]点醒我了
如果我用了你这句话,而你看到了,望不要介意
我懂了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2