Understanding Java bytes

后端 未结 6 897
抹茶落季
抹茶落季 2020-12-31 18:48

So at work yesterday, I had to write an application to count the pages in an AFP file. So I dusted off my MO:DCA spec PDF and found the structured field BPG (Begin Pag

6条回答
  •  轮回少年
    2020-12-31 19:04

    Not sure what you really want :) I assume you are asking how to extract a signed multi-byte value? First, look at what happens when you sign extend a single byte:

    byte[] b = new byte[] { -128 };
    int i = b[0];
    System.out.println(i); // prints -128!
    

    So, the sign is correctly extendet to 32 bits without doing anything special. The byte 1000 0000 extends correctly to 1111 1111 1111 1111 1111 1111 1000 0000. You already know how to suppress sign extension by AND'ing with 0xFF - for multi byte values, you want only the sign of the most significant byte to be extendet, and the less significant bytes you want to treat as unsigned (example assumes network byte order, 16-bit int value):

    byte[] b = new byte[] { -128, 1 }; // 0x80, 0x01
    int i = (b[0] << 8) | (b[1] & 0xFF);
    System.out.println(i); // prints -32767!
    System.out.println(Integer.toHexString(i)); // prints ffff8001
    

    You need to suppress the sign extension of every byte except the most significant one, so to extract a signed 32-bit int to a 64-bit long:

    byte[] b = new byte[] { -54, -2, -70, -66 }; // 0xca, 0xfe, 0xba, 0xbe
    long l = ( b[0]         << 24) |
             ((b[1] & 0xFF) << 16) |
             ((b[2] & 0xFF) <<  8) |
             ((b[3] & 0xFF)      );
    System.out.println(l); // prints -889275714
    System.out.println(Long.toHexString(l)); // prints ffffffffcafebabe
    

    Note: on intel based systems, bytes are often stored in reverse order (least significant byte first) because the x86 architecture stores larger entities in this order in memory. A lot of x86 originated software does use it in file formats, too.

提交回复
热议问题