0

我正在尝试将出生日期(三个整数)转换为字节并将其转换回来,但我遇到了问题。我必须使用位操作对其进行转换,并通过多播服务器发送数据并接收它并改回 int。服务器工作正常,但位操作对我来说很难。代码有什么问题:

兑换:

      int D=12; 
      int M=9; 
      int Y=1983;
      short DMY=0; 
      DMY = (short)(DMY | (D << 19));
      DMY = (short)(DMY | (M << 15));
      DMY = (short)(DMY | Y); 
      byte[] data = new byte[3];
      data[0] = (byte)(DMY >>> 8 );
      data[1] = (byte)(DMY >>> 16 );
      data[2] = (byte)(DMY & 0xffff);

转换回来:

           byte[] rec_data = new byte[3];
           rec_data = dp.getData();
           short Rec_dmy;


           Rec_dmy = (short)(rec_data[0] & 0xff);
           Rec_dmy = (short) (Rec_dmy << 8);
           Rec_dmy = (short)(Rec_dmy | (rec_data[1] & 0xff));
           Rec_dmy = (short) (Rec_dmy << 8);
           Rec_dmy = (short)(Rec_dmy | (rec_data[2] & 0xffff));

           byte tmp = (byte) ((Rec_dmy  >>> 19) & 0x1F);
           byte tmp2 = (byte) ((Rec_dmy >>> 15) & 0x1FF);
           byte tmp3 = (byte) (Rec_dmy & 0x7F);       

            System.out.println(tmp);
            System.out.println(tmp2);
            System.out.println(tmp3);

Println 给出以下答案:31 -1 63

它不接近原始的 12 9 1983

4

3 回答 3

3

Shorts 只能容纳 16 位;您正在尝试打包更多(例如,将日期左移 19,一旦转换为空头,将导致全零值)。您需要使用 int 或 long 来保存所有字段。

事实上,你有几件事情发生在不正确的位操作上。

我的建议是放弃位操作,只将日、月和年作为单独的字段发送:日和月各一个字节,年两个(短)字节。这需要 4 个字节(只有一个额外的字节),但需要更少的摆弄才能正确。

于 2012-08-25T05:26:25.343 回答
1

Its not easy, but you have to work systematically to ensure your operations don't a) lose information b) decode the reverse of how you have encoded.

int D = 12;
int M = 9;
int Y = 1983;
int DMY = (D << 19) | (M << 15) | Y;
byte[] data = new byte[3];
data[0] = (byte) (DMY >>> 16);
data[1] = (byte) (DMY >>> 8);
data[2] = (byte) DMY;

int DMY2 = ((data[0]&0xFF) << 16) | ((data[1]&0xFF) << 8) | (data[2]&0xFF);
int D2 = DMY2 >>> 19;          // no mask required
int M2 = (DMY2 >>> 15) & 0x0F; // 4 bits mask
int Y2 = DMY2 & 0x7FFF;        // 15 bit mask
System.out.println(D2 + "/" + M2 + "/" + Y2);

prints

12/9/1983
于 2012-08-25T07:15:16.890 回答
0

首先,您需要至少 14 位来表示最大值为 9999 的年份,因为2^14 > 9999 && 2 ^ 13 < 9999. 月的最少位数是 4(最大 12),日是 5(最大 31)。因此,您可以使用一个短整数(16 位)来表示每一天和每一个月的年份和字节(8 位)。所以你得到一个 32 位的 int。

public int encoded(short year, byte month, byte day){
    int data =0;
    data = year & 0xFFFF;
    data =(data << 8)|(month & 0xFF)
    data =(data << 8)|(day & 0xFF)
    return data;
}

public void decode(int data){
    int day = data & 0xFF;
    int month = (data >> 8) & 0xFF;
    int year = (data >> 16) & 0xFFFF;
}
于 2012-08-25T05:40:54.377 回答