长包含许多整数

时间:2018-10-26 21:09:29

标签: java

我的工作是将多个数字分配给一个长整数。 1. 17位数字 2. 7位数字 3. 17位数字 4. 7位数字 5. 13位数字 6. 3位数字

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

当我编译它时,我得到了错误的数字。 ( 像这样 ) 来电者:2012年 来电区:92 被叫者:16398 Callee_zone:123 持续时间:0 关税: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);

    //---Printing---

    System.out.println("Caller:      " + caller);
    System.out.println("Caller_zone: " + caller_zone);
    System.out.println("Callee:      " + callee);
    System.out.println("Callee_zone: " + callee_zone);
    System.out.println("Duration:    " + duration);
    System.out.println("Tariff:      " + tariff);
    //-----------------------------------------------   
}

}`

2 个答案:

答案 0 :(得分:2)

编码器为每个项目分配错误的位数。例如:

//---1st---
example = caller;
res = res | example;
res = res << 17;

好吧,让我们首先简化一下:

//---1st---
res = res | caller;
res = res << 17;

由于移位是最后一步,因此它为 next 项目分配了17位。但是caller的大小是17,而不是下一个项目caller_zone的大小。因此大小不正确,事情变得混乱起来。

它应该看起来像这样,在新的位上写上“ before”:

//---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;

此外,解码器错过了移位。出于明显的原因,移位模式应该是编码器的“镜像”,因此检查它是否“对齐”非常容易。掩码比较难检查,尤其是十进制会掩盖真实值。

答案 1 :(得分:1)

通过执行以下操作可以大大缩短您的代码:

public static int compareTimeOfDates(Date date1, Date date2) {
    return convertToLocalTimeViaInstant(date1).compareTo(convertToLocalTimeViaInstant(date2));
}

测试

public static long encode(int caller, int caller_zone,
                          int callee, int callee_zone,
                          int duration, int tariff) {
    return ((caller      & 0x1FFFFL/*17 bits*/) << 47)
         + ((caller_zone & 0x0007FL/* 7 bits*/) << 40)
         + ((callee      & 0x1FFFFL/*17 bits*/) << 23)
         + ((callee_zone & 0x0007FL/* 7 bits*/) << 16)
         + ((duration    & 0x01FFFL/*13 bits*/) <<  3)
         +  (tariff      & 0x00007L/* 3 bits*/);
}
public static int[] decode(long res) {
    return new int[] {
        (int) (res >> 47) & 0x1FFFF/*17 bits*/, // caller
        (int) (res >> 40) & 0x0007F/* 7 bits*/, // caller_zone
        (int) (res >> 23) & 0x1FFFF/*17 bits*/, // callee
        (int) (res >> 16) & 0x0007F/* 7 bits*/, // callee_zone
        (int) (res >>  3) & 0x01FFF/*13 bits*/, // duration
        (int)  res        & 0x00007/* 3 bits*/  // tariff
    };
}

输出

System.out.println(Arrays.toString(decode(encode(130999, 101, 7777, 99, 7000, 6))));

[130999, 101, 7777, 99, 7000, 6] 方法中,此处应用的一个技巧是encode AND运算符,其文字为&,将long的值隐式扩展为{{1} } 之前 int左移值。在long方法中进行位屏蔽的另一个好处是,太大的输入会被“截断”到支持的位数,从而防止溢出。

此外,可以将<<有符号扩展的移位运算符更改为encode无符号移位运算符,但这没有关系,因为在之后应用了位掩码移位,因此无论如何都将符号位丢弃。