Representing a number in a byte array (java programming)

不羁的心 提交于 2019-12-10 13:07:06

问题


I'm trying to represent the port number 9876 (or 0x2694 in hex) in a two byte array:

class foo {
     public static void main (String args[]) {
   byte[] sendData = new byte[1];

   sendData[0] = 0x26;
   sendData[1] = 0x94;
     }
}

But I get a warning about possible loss of precision:

foo.java:5: possible loss of precision
found   : int
required: byte
   sendData[1] = 0x94;
                 ^
1 error

How can I represent the number 9876 in a two byte array without losing precision?

NOTE: I selected the code by @Björn as the correct answer, but the code by @glowcoder also works well. It's just a different approach to the same problem. Thank you all!


回答1:


My first answer would be bitshifting, but on a second thought I think using outputstreams could be better and more simple to understand. I usually avoid casting, but if you're not going for a generic solution I guess that would be okay. :)

Using streams, a generic solution:

public byte[] intToByteArray(final int i) throws java.io.IOException {
    java.io.ByteArrayOutputStream b = new java.io.ByteArrayOutputStream();
    java.io.DataOutputStream d = new java.io.DataOutputStream(b);
    d.writeInt(i);
    d.flush();

    return b.toByteArray();
}

And to reverse it:

public int byteArrayToInt(final byte[] b) throws IOException {
    java.io.ByteArrayInputStream ba = new java.io.ByteArrayInputStream(b);
    java.io.DataInputStream d = new java.io.DataInputStream(ba);

    return d.readInt();
}



回答2:


Have you tried casting to a byte ? e.g.

sendData[1] = (byte)0x94;



回答3:


0x94 is 148 in decimal, which exceeds the range of byte in java (-128 to 127). You can do one of the following:

1) A cast will work fine because it will preserve the binary representation (no meaningful bits are truncated for 0x00 to 0xFF):

 sendData[1] = (byte)0x94; 

2) The binary representation of 0x94 as a signed byte is -108 (-0x6C), so the following will have the same effect:

sendData[1] = -0x6C; //or -108 in decimal



回答4:


Björn gave a good generic answer with using streams. You can also do this same thing using java.nio.ByteBuffer which results in slightly less code and you could also control endianess (byte order) of the output.

To create the byte array:

public static byte[] toByteArray(int bits) {
    ByteBuffer buf = ByteBuffer.allocate(4);
    buf.putInt(bits);
    return buf.array();
}

To reverse it:

public static int fromByteArray(byte[] b) {
    ByteBuffer buf = ByteBuffer.wrap(b);
    return buf.getInt();
}



回答5:


You have to cast to (byte) as default number type in java is int, which is bigger than byte. As long as the value fits in byte it is ok to cast.




回答6:


Try this:

sendData[0] =(byte)0x26
sendData[1] =(byte)0x94

Or this:

sendData[0] =(byte)38
sendData[1] =(byte)148

You must cast data into byte in order to assign it to a byte!

That does not mean you lost precision, just writing 0x26 means an int to Java compiler..

But also note: range of a byte is from -128 to 127, so in case of 0x94=148 it will be represented after byte casting as '-108' , so it will not work correctly in mathematical computations..




回答7:


It's because everything in Java is signed. 0x94 (148) is greater than Byte.MAX_VALUE(2^7-1).

What you need is

public static byte[] intToByteArray(int value) {
    byte[] b = new byte[4];
    for (int i = 0; i < 4; i++) {
        int offset = (b.length - 1 - i) * 8;
        b[i] = (byte) ((value >>> offset) & 0xFF);
    }
    return b;
}


来源:https://stackoverflow.com/questions/2868885/representing-a-number-in-a-byte-array-java-programming

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!