日期:2014-05-20  浏览次数:20718 次

【高分请教】JAVA位移熟悉的兄弟进
本帖最后由 cscript 于 2012-12-19 18:24:22 编辑

public static long readUnit64(ByteBuffer buf){
int l = 0;
long rst = 0L;
while(l<64){
int t = buf.get();
rst |= (long)((t & 127) << l);
if((t & 128) == 0)
return rst;
l += 7;
}
return 0;
}

public static void writeUnit64(ByteBuffer buf, long val){
while(true){
if ((0xFFFFFF80 & val) == 0L){
buf.put((byte)(int)val);
break;
}
buf.put((byte)(128 | 127 & (int)val));
val >>>= 7;
}
}

public static void main(String[] args) {
long t = System.currentTimeMillis()/1000; //问题在这里,不除以1000就是错的
System.out.println("原始数据:"+t);
ByteBuffer buf = ByteBuffer.allocate(128);
writeUnit64(buf, t);
buf.flip();
System.out.println("原始数据:"+readUnit64(buf));
}


如上 代码所视,小弟最近分析一socket协议 其中用到 writeUnit64 和 readUnit64 方法来用于 把一long类型的数据转换为byte和把一byte数组读取为long

当处理的long数据长度为10位的时候,这两个方法都很正常
但是 当长度为13位的时候 writeUnit64 正常 但 readUnit64 出来的数据是错的还是负数

小弟翻阅谷哥,度娘 未果,特发此贴, 希望高手解惑


PS:小弟发此贴不是为了解决怎么把long转换为byte数组,而是把writeUnit64后的数据正确的读取出来,谢谢各位
------解决方案--------------------
不是很清楚,
不过你可以参考
1. datainputstream的readlong
2. dataoutputstream的writelong
------解决方案--------------------
把t改成long即可:
另外判断条件换一下,避免异常。代码:

public static long readUnit64(ByteBuffer buf){
    int l = 0;
    long rst = 0L;
    //while(l<64){
            while(buf.position()<buf.limit()){//换一下判断条件
        long t = (int)buf.get();//t改成long 
        rst 
------解决方案--------------------
= (t & 127) << l;
        if((t & 128) == 0)
            return rst;
        l += 7;
    }
    return rst;//返回rst.
}

------解决方案--------------------
抛砖引玉一下

首先你的 writeUnit64 中的
 buf.put((byte)(128 
------解决方案--------------------
 127 & (int)val));
这一句 存在问题 

val 你定义为long型  在这里被强转成了 int型  丢失了精度  

如果没分析错的话  问题不是 多少位数字 
你给的数只要大于Integer.MAX_VALUE 就出问题

long强转int  直接丢弃 前4个字节

反过来 int转long 就是根据正负数在前面加上4个字节的0或1

readUnit64方法我没看 
------解决方案--------------------