java位操作错误(转换为字节并转换回)

vxf3dgd4  于 2021-07-09  发布在  Java
关注(0)|答案(3)|浏览(359)

我正试图将出生日期(三个整数)转换为字节,并将其转换回来,但我有一个问题。我必须使用位操作来转换它,通过多播服务器发送数据,然后接收数据并将其更改回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-163
它不接近原来的12 9 1983

bqf10yzr

bqf10yzr1#

短裤只能容纳16位;你正在尝试打包更多的内容(例如,将日期向左移动19,这将导致一次转换为一个短值时的全零值)。您需要使用int或long来保存所有字段。
实际上,位操作中存在一些不正确的地方。
我的建议是放弃位操作,只将日、月和年作为单独的字段发送:日和月各发送一个字节,年发送两个字节。这需要4个字节(只需要一个额外的字节),但要想做对,所需的处理要少得多。

z8dt9xmd

z8dt9xmd2#

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

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;
}
uidvcgyl

uidvcgyl3#

这并不容易,但你必须系统地工作,以确保你的操作不会a)丢失信息b)解码与你编码的方式相反。

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

印刷品

12/9/1983

相关问题