我们看下面这段代码

  

  输出的结果的是128,这个没什么疑问

    

  但是当我们不改变数值仅仅加了一个强制转换后

  

  这时我们会发现结果会变成负的128.这时候我们就要怀疑了,为什么会出现这样的结果呢?

    

  对于这个问题,我们就要深入到计算机的组成原理中去了。计算机存储数据是用二进制的0和1代码存储的,也就是硬件层面的高低电平。但是在用户编程层面,我们仍然是用着我们习惯的十进制或者其它方便计算的进制的进行编程的。在java的基本数据类型中,byte类型的大小是一个字节即8个比特,放到计算中存储就是8个存储空间,每个存储空间可以放0或者1;同理int类型是四个字节大小,即32个bit大小。计算机为了方便表示数的正负时将数的二进制码的最高位作为数的正负表示,通常是0表示正数,1表示负数。这样在真正在表示数时候只有比原类型总共空间大小少一位的位数来表示,例如int型的数据空间大小是32,但只有31个空间用来表示数值部分的,最高位用来表示正负。同时又为了方便进行数值的加减操作,引入了补码这个概念,补码是在源码的基础上除符号位外进行的各位取反后再加1获得的,但是正数的补码是不变的,还是源码本身。例如10的源码(01010)B,补码也是(01010)B,-10的源码是(11010)B,补码则是(10110)B,计算机存储时,存的就是-10的补码(10110)B,而不是(11010)B.

  弄清楚这个后,我们再来看int型的128在计算机中存储二进制码是0000 0000 0000 0000 0000 000 1000 0000 占据空间为32,最高位0表示这个数是正数,但是当我们强制转换这个int型的数据为byte型,由于byte型只占据一个字节8个比特的空间,就只会截取int型数据的低八位空间中的数据作为新的数据,高位舍弃,也就是1000 0000,此时这里面的1表示这个新的数据是个负数,而且是补码形式,要算出原数值就要先-1得0111 1111再各位取反是1000 0000,这个值就是真实值的绝对值128,加上符号后就是-128. 因此在进行强制转换时我要要注意数据的溢出问题。

 

posted on 2017-02-21 23:43  人生第一步  阅读(2931)  评论(1编辑  收藏  举报