Long 包含许多 int

我的练习是将多个数字分配给一个 long。1. 17 位数字 2. 7 位数字 3. 17 位数字 4. 7 位数字 5. 13 位数字 6. 3 位数字


一个函数将这 6 个整数打包成一个 long 第二个函数从一个 long 中读取这 6 个整数并打印信息


当我编译这个时,我得到了错误的数字。(像这样) Caller: 2012 Caller_zone: 92 Callee: 16398 Callee_zone: 123 Duration: 0 Tariff: 6


`


public class Problem_3_5{

public static void main(String[] args){

    info(encode(130999, 101, 7777, 99, 7000, 6));


}

public static long encode(int caller, int caller_zone,

                          int callee, int callee_zone,

                          int duration, int tariff) {

    long res = 0;

    long example = 0;


    //---1st---

    example = caller;

    res = res | example;

    res = res << 17;


    //---2nd---

    example = caller_zone;

    res = res | example;

    res = res << 7;


    //---3rd---

    example = callee;

    res = res | example;

    res = res << 17;


    //---4th---

    example = callee_zone;

    res = res | example;

    res = res << 7;


    //---5th---

    example = duration;

    res = res | example;

    res = res << 13;


    //---6th---

    example = tariff;

    res = res | example;


    //--END---

    return res;

    //---------------------------

}


public static void info(long res){

    //---TARIFF----

    long tariff = 0;

        tariff = (res & 7);

        res = res >>> 3;


    //---DURATION---

    long duration = 0;

        duration = (res & 8191);

        res = res >>> 13;


    //---CALLEE_ZONE---

    long callee_zone = 0;

        callee_zone = (res & 127);

        res = res >>> 7;


    //---CALLEE---

    long callee = 0;

        callee = (res & 131071);

        res = res >>> 17;


    //---CALLER_ZONE---

    long caller_zone = 0;

        caller_zone = (res & 127);


    //---CALLER---

    long caller = 0;

        caller = (res & 131071);

慕桂英4014372
浏览 104回答 2
2回答

繁华开满天机

编码器为每个项目分配了错误的位数。例如://---1st---example = caller;res = res | example;res = res << 17;好吧,让我们首先简化一下://---1st---res = res | caller;res = res << 17;由于移位是最后一步,因此它为下一项分配 17 位。但是 17 是 的大小caller,而不是下一项 caller_zone 的大小。所以尺寸是错误的,事情变得混乱。它应该看起来更像这样,在新位中写入“之前”的移位://---1st---res |= caller;//---2nd---res <<= 7;res |= caller_zone;//---3rd---res <<= 17;res |= callee;//---4th---res <<= 7;res |= callee_zone;//---5th---res <<= 13;res |= duration;//---6th---res <<= 3;res |= tariff;此外,解码器错过了一个转变。出于显而易见的原因,移位模式应该是编码器的“镜子”,因此很容易检查它是否“对齐”。掩码有点难以检查,尤其是在十进制中,它掩盖了真实值。

慕无忌1623718

通过这样做,您的代码可以大大缩短:public static long encode(int caller, int caller_zone,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int callee, int callee_zone,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int duration, int tariff) {&nbsp; &nbsp; return ((caller&nbsp; &nbsp; &nbsp; & 0x1FFFFL/*17 bits*/) << 47)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ ((caller_zone & 0x0007FL/* 7 bits*/) << 40)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ ((callee&nbsp; &nbsp; &nbsp; & 0x1FFFFL/*17 bits*/) << 23)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ ((callee_zone & 0x0007FL/* 7 bits*/) << 16)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ ((duration&nbsp; &nbsp; & 0x01FFFL/*13 bits*/) <<&nbsp; 3)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+&nbsp; (tariff&nbsp; &nbsp; &nbsp; & 0x00007L/* 3 bits*/);}public static int[] decode(long res) {&nbsp; &nbsp; return new int[] {&nbsp; &nbsp; &nbsp; &nbsp; (int) (res >> 47) & 0x1FFFF/*17 bits*/, // caller&nbsp; &nbsp; &nbsp; &nbsp; (int) (res >> 40) & 0x0007F/* 7 bits*/, // caller_zone&nbsp; &nbsp; &nbsp; &nbsp; (int) (res >> 23) & 0x1FFFF/*17 bits*/, // callee&nbsp; &nbsp; &nbsp; &nbsp; (int) (res >> 16) & 0x0007F/* 7 bits*/, // callee_zone&nbsp; &nbsp; &nbsp; &nbsp; (int) (res >>&nbsp; 3) & 0x01FFF/*13 bits*/, // duration&nbsp; &nbsp; &nbsp; &nbsp; (int)&nbsp; res&nbsp; &nbsp; &nbsp; &nbsp; & 0x00007/* 3 bits*/&nbsp; // tariff&nbsp; &nbsp; };}测试System.out.println(Arrays.toString(decode(encode(130999, 101, 7777, 99, 7000, 6))));输出[130999, 101, 7777, 99, 7000, 6]在该encode方法中,这里应用的一个技巧是&带有long文字的AND 运算符,在左移int值long 之前 隐式地将值扩大到<<。在该encode方法中进行位屏蔽的额外好处是过大的输入被“截断”为支持的位数,从而防止溢出。此外,有>>符号扩展移位运算符可以更改为>>>无符号移位运算符,但这无关紧要,因为位掩码是在移位后应用的,因此无论如何都会丢弃符号位。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java