java byte 负数 int_java byte负数转换int失真?

byte aa=-1; //java 补码后为1111 1111

int bb=aa&0xFF;//保持2进制一致进行位与操作

system.out.printf(bb);

输出:255

提示:要了解这个问题首先要了解原码、反码、补码,这里不介绍了,自己百度吧。

根据我的理解,byte=-1时,-1 & 0xff 是等于255,补码是1111 1111

Java中byte是有符号的,但byte输出到控制台或者检测到byte可能转化为int或者和int相计算时,是当作int类型(32位)输出的,会将byte的高位自动补1,扩充到32位,即1111 1111 1111 1111 1111 1111 1111 1111,此时的补码和byte(8位)的补码1111 1111对应的十进制值是一样的,都是-1。

计算机底层为了为了电路方便(具体为什么去看原码、反码、补码),都是采用补码运算(背书),那么从上面知道:

-1 & 0xff = 1111 1111 1111 1111 1111 1111 1111 1111 & 1111 1111 = 0000 0000 0000 0000 0000 0000 1111 1111 = 255

所以结果转化为十进制就是255。

归根结底的原因就是Java的byte类型范围是-128~127,是有符号的,8位开头第一个数字是代表符号的,最后变成32位就被当作正数了。

在C#中byte就不会有这个问题,因为byte范围是0~255,sbtye才相当于Java的byte,避免了这个问题。所以快去学C#……(#滑稽)

system.out.printf((byte)bb); 这样就会输出-1了

除此之外,为什么外面很多代码中btye[]转int都带上&0xFF呢

因为

第一点:int是4字节,int -1时,补码是1111 1111 1111 1111 1111 1111 1111 1111 。

第二点:btye(8位)如上述所说的Java会自动补位1,变成32位,所以为了不让自动补高位的1影响计算,需要与0xFF(1111 1111)相与运算,变成0000 0000 0000 0000 0000 0000 1111 1111。就跟上面的计算是一个样子的

高位为0了,就不会影响接下来的计算了。(可能没解释清楚,大概就这个意思吧,具体可以看看相与&运算时,各种情况的各种结果)

byte[] aa = new byte[]{ -1,0,0,0};

//a[0] bb 最后的字节 表示1111 1111

//a[1] cc 倒数第二个字节 分别表示 0000 0000 和 1111 1111

//a[2] dd 第二个字节 分别表示 0000 0000 和 1111 1111

//a[3] ee 第一个字节 分别表示 0000 0000 和 1111 1111 (最高位&0xFF可以省略)

int bb= aa[0] & 0xFF;

int cc = 0xFF & 0xFF;

int dd = 0xFF & 0xFF;

int ee = 0xFF & 0xFF;

System.out.println((int)((aa[0] & 0xFF)|(aa[1] & 0xFF)<<8|(aa[2] & 0xFF)<<16|(aa[3] & 0xFF)<<24)); //255

System.out.println((int)((aa[0])|(aa[1])<<8|(aa[2])<<16|(aa[3])<<24)); //-1

System.out.println((int)((bb)|(cc)<<8|(dd)<<16|(ee)<<24)); //-1

System.out.println(bb); //255

System.out.println((byte)bb); //-1

俺也是依葫芦画瓢,有错,欢迎指导

参考byte为什么要与上0xff? - 陈其苗 - 博客园​www.cnblogs.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值