首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

【高分请问】JAVA位移熟悉的兄弟进

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

【高分请教】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方法我没看 
------解决方案--------------------


5楼的同学误会了,楼主的程序只使用了 7 个 bit 来进行存储,所以安全绕过符号位。

楼主程序的核心问题是强转 long 的时机错误,修正如下:


    public static long readUnit64fix(ByteBuffer buf) {
        int l = 0;
        long rst = 0L;
        while (l < 64) {
            int t = buf.get();
            rst 
[解决办法]
= ((long) (t & 0x7f) << l); // 只是这句话而已
            if ((t & 0x80) == 0)
                return rst;
            l += 7;
        }
        return 0;
    }

[解决办法]
同意楼上

(t & 127) << l 

这操作是在int范围内进行的,如果期望值大于32位,它仍无法自动拓展成long型

有些地方貌似还可以再优化一下
int t = buf.get(); //这里int改为byte较好
buf.put((byte)(int)val); //这里的int转型貌似没必要
buf.put((byte)(128 
[解决办法]
 127 & (int)val)); //这里int转型貌似也没必要

热点排行