java位移运算导致数值为负数

来源:互联网 发布:usb端口定义 编辑:程序博客网 时间:2024/06/05 01:18

问题表现:java位移运算导致数值为负数

 

问题分析:

关键源代码:

int startTime = (int) (promotions >> 32);

int p = (int) (promotions & 0xFFFFFFFF);

int duraTime = p >> 16;

int rate = (int) (p & 0xFFFF);

int endTime = startTime + duraTime * 60;

 

源代码中:int duraTime = p >> 16;右移位后,符号位为1,导致了持续时间duraTime为负数的情况。

 

摘取代码,逐步分析验证:

Promotions= 5682372155986092840

int startTime = (int) (promotions >> 32);

int p = (int) (promotions & 0xFFFFFFFF); //p 的二进制为10001111 00011111 00100011 00101000(int一共32bit),被解析为负值

int duraTime = p >> 16;             //p被认为是负数,右移位的时候,左边多出来的补1, duraTime的二进制为11111111 11111111 10001111 00011111(duraTime被解析为负值)

int rate = (int) (p & 0xFFFF);

int endTime = startTime + duraTime * 60;

 

 

正确的代码1:

int startTime = (int) (promotions >>> 32); // 无符号右移,防止出现负数

int p = (int) (promotions & 0xFFFFFFFF);  //p 的二进制为10001111 00011111 00100011 00101000(int一共32bit)

int duraTime = p >>> 16;          //右移位的时候,左边多出来的补0, duraTime的二进制为00000000 00000000 10001111 00011111(duraTime被解析为负值)

int rate = (int) (p & 0xFFFF);

int endTime = startTime + duraTime * 60;


正确的代码2:

 不适用int类型,而使用long类型,这样符号位第一位则为0,位移的时候,也不会出现为负数的情况。

 

附带的java位运算相关的知识:

位移运算的过程:

 

移位运算符

包括:

“>> 右移,高位补符号位”;

“>>> 无符号右移,高位补0”;

“<< 左移”;

 

例子:

-5>>3=-1

1111 1111 1111 1111 1111 1111 1111 1011

1111 1111 1111 1111 1111 1111 1111 1111

因为是负数,高位补1

 

 

35 >> 2=8

0000 0000 0000 0000 0000 0000 0010 0011  

0000 0000 0000 0000 0000 0000 0000 1000 

因为是正数,高位补0

 

 

-5>>>3=536870911 

1111 1111 1111 1111 1111 1111 1111 1011

0001 1111 1111 1111 1111 1111 1111 1111

因为是无符号位移,高位强制补0


0 0
原创粉丝点击