Java移位操作遇到的问题?

myowenbin 2012-09-12 01:17:59
程序的目的是:把一个小于0x7FFF的数存放在两个byte字节里(setRecvcounter方法);
       需要时从两个byte字节中还原这个int型数据(getRecvcounte方法);
问题:
为何这个程序在输出时,有时是对的有时不对,比如counter=0x1234,可以还原,counter=0x3773,无法还原,问题出在哪里?
class Test {
byte ctrlbyte3;
byte ctrlbyte4;
public static void main(String[] args) {
int counter=0x7fff;
Test a=new Test();
a.setRecvCounter(counter);
System.out.println("counter = "+counter);
System.out.println("a.getRecvCounter() = "+a.getRecvCounter());
}
private int getRecvCounter() {
return (ctrlbyte3 >> 1) + (ctrlbyte4 << 7);
}
private void setRecvCounter(int recvcounter) {
ctrlbyte3 = (byte) ((recvcounter << 1) & 0xff);
ctrlbyte4 = (byte) ((recvcounter >> 7) & 0xff);
}
}
问题补充:
在移位操作的时候,Java会把byte型数据自动转化为int型,<<左移是低位补零,>>右移是符号位扩展
...全文
266 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Alexander 2012-09-12
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

你的代码把0x7FFF换成0x3FFF输出就不对了
引用 10 楼 的回复:

这算是Java的缺陷之一吧(当然,从Java的设计思想上看算不上缺陷),Java中不存在无符号数。如果想用Java实现较接近底层的操作需要对数据作一些处理。毕竟Java设计的期望之一就是架空底层实现,让程序员把精力放到逻辑实现上。
Java code

public class Test1 {
byt……
[/Quote]
抱歉,把以前写C程序的思路照搬了:

private int getRecvCounter() {
return ((ctrlbyte3 >> 1 & 0x7f) + (ctrlbyte4 << 7 & 0x7f80));
}
myowenbin 2012-09-12
  • 打赏
  • 举报
回复
你的代码把0x7FFF换成0x3FFF输出就不对了
[Quote=引用 10 楼 的回复:]

这算是Java的缺陷之一吧(当然,从Java的设计思想上看算不上缺陷),Java中不存在无符号数。如果想用Java实现较接近底层的操作需要对数据作一些处理。毕竟Java设计的期望之一就是架空底层实现,让程序员把精力放到逻辑实现上。
Java code

public class Test1 {
byte ctrlbyte3;
byte ctrlbyte4;

publ……
[/Quote]
Alexander 2012-09-12
  • 打赏
  • 举报
回复
计算机进行运算的基本单位是寄存器,CPU寄存器位数总是与字长(即int的长度)相同。所以作位运算时会先把操作数从byte型扩散到int型。对于无符号数,会在高位字节上补0,这样不会影响运算结果;而Java没有无符号数,有符号数的扩散会根据byte的符号位进行处理,非负数补0,负数补1,因此需要在运算时需要用位与将多补出来的1去掉。
Alexander 2012-09-12
  • 打赏
  • 举报
回复
这算是Java的缺陷之一吧(当然,从Java的设计思想上看算不上缺陷),Java中不存在无符号数。如果想用Java实现较接近底层的操作需要对数据作一些处理。毕竟Java设计的期望之一就是架空底层实现,让程序员把精力放到逻辑实现上。

public class Test1 {
byte ctrlbyte3;
byte ctrlbyte4;

public static void main(String[] args) {
Test1 t = new Test1();

t.setRecvCounter(0x7fff);
System.out.printf("%x\n", t.ctrlbyte3);
System.out.printf("%x\n", t.ctrlbyte4);
System.out.printf("%x\n", t.getRecvCounter());
}

private int getRecvCounter() {
return ((ctrlbyte3 >> 1 & 0x7f) + (ctrlbyte4 & 0xff << 7));
}

private void setRecvCounter(int recvcounter) {
ctrlbyte3 = (byte) (recvcounter << 1);
ctrlbyte4 = (byte) (recvcounter >> 7);
}
}
MiceRice 2012-09-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
谢谢你的代码,确实运行无误,我想知道,我的代码为啥不对,问题出在哪里?
[/Quote]

说的很清楚啊,符号位你没处理啊。

byte 的 0xff 转换成int就是 0xffffffff,所以强转int后,先 & 0xff => 0x000000ff
nmyangym 2012-09-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

主要是符号位的处理,得先把符号位给消灭掉,你这样试试看:

Java code

private int getRecvCounter() {
return ((((int) ctrlbyte3) & 0xff) >> 1) + ((((int) ctrlbyte4) & 0xff) << 7);
}
[/Quote]
+1
这是问题的关键!
myowenbin 2012-09-12
  • 打赏
  • 举报
回复
我的为什么不对呢?问题在哪里?
[Quote=引用 3 楼 的回复:]

试试这样:
Java code

class Test2
{
byte ctrlbyte3;
byte ctrlbyte4;
public static void main(String[] args)
{
int counter=0x3773;
Test2 a=new Test2();
a.setRecvCo……
[/Quote]
myowenbin 2012-09-12
  • 打赏
  • 举报
回复
谢谢你的代码,确实运行无误,我想知道,我的代码为啥不对,问题出在哪里?
lost_guy_in_scut 2012-09-12
  • 打赏
  • 举报
回复
楼主试下无符号右移吧>>>
MiceRice 2012-09-12
  • 打赏
  • 举报
回复
主要是符号位的处理,得先把符号位给消灭掉,你这样试试看:


private int getRecvCounter() {
return ((((int) ctrlbyte3) & 0xff) >> 1) + ((((int) ctrlbyte4) & 0xff) << 7);
}
nmyangym 2012-09-12
  • 打赏
  • 举报
回复
试试这样:

class Test2
{
byte ctrlbyte3;
byte ctrlbyte4;
public static void main(String[] args)
{
int counter=0x3773;
Test2 a=new Test2();
a.setRecvCounter(counter);
System.out.println("counter = "+counter);
System.out.println("a.getRecvCounter() = "+a.getRecvCounter());
}
private int getRecvCounter()
{
return (ctrlbyte3 << 8) + ((ctrlbyte4)&0xff); //
}
private void setRecvCounter(int recvcounter)
{
ctrlbyte3 = (byte) ((recvcounter >> 8) & 0xff); //保存高8位.
ctrlbyte4 = (byte) ((recvcounter) & 0xff); //保存低8位.
}
}
myowenbin 2012-09-12
  • 打赏
  • 举报
回复
咋没人回答呢,csdn人气有这么差吗,有木有高人呀?
cfm2000 2012-09-12
  • 打赏
  • 举报
回复
你自己把recvcounter定义成integer了。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧