Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
表示字节数组中的数字(java编程)_Java_Arrays_Bytearray_Hex - Fatal编程技术网

表示字节数组中的数字(java编程)

表示字节数组中的数字(java编程),java,arrays,bytearray,hex,Java,Arrays,Bytearray,Hex,我试图在一个双字节数组中表示端口号9876(或十六进制的0x2694): class foo { public static void main (String args[]) { byte[] sendData = new byte[1]; sendData[0] = 0x26; sendData[1] = 0x94; } } public static byte[] toByteArray(int bits) { ByteBuffer buf

我试图在一个双字节数组中表示端口号9876(或十六进制的0x2694):

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

   sendData[0] = 0x26;
   sendData[1] = 0x94;
     }
}
public static byte[] toByteArray(int bits) {
    ByteBuffer buf = ByteBuffer.allocate(4);
    buf.putInt(bits);
    return buf.array();
}
但我得到一个警告,可能会失去精度:

foo.java:5: possible loss of precision
found   : int
required: byte
   sendData[1] = 0x94;
                 ^
1 error
如何在不损失精度的情况下在两字节数组中表示数字9876


注意:我选择了@Björn的代码作为正确答案,但是@glowcoder的代码也很有效。对于同一个问题,这只是一种不同的方法。谢谢大家!

您是否尝试强制转换到一个字节?e、 g

sendData[1] = (byte)0x94;
您必须强制转换为(byte),因为java中的默认数字类型是int,大于byte。只要值适合字节,就可以进行强制转换。

尝试以下操作:

sendData[0] =(byte)0x26
sendData[1] =(byte)0x94
或者这个:

sendData[0] =(byte)38
sendData[1] =(byte)148
您必须将数据强制转换为字节才能将其分配给字节

这并不意味着您失去了精度,只是编写
0x26
意味着一个int-to-Java编译器


但也要注意:字节的范围是从-128到127,因此在
0x94=148的情况下,它将在字节转换后表示为“-108”,因此它在数学计算中无法正常工作。

这是因为Java中的所有内容都是有符号的。0x94(148)大于Byte.MAX_值(2^7-1)

你需要的是

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;
}
公共静态字节[]intToByteArray(int值){
字节[]b=新字节[4];
对于(int i=0;i<4;i++){
整数偏移=(b.长度-1-i)*8;
b[i]=(字节)((值>>>偏移量)和0xFF);
}
返回b;
}

0x94的十进制数为148,超出了java中的字节范围(-128到127)。 您可以执行以下操作之一:

1) 强制转换可以正常工作,因为它将保留二进制表示(对于0x00到0xFF,没有有意义的位被截断):

2) 0x94作为有符号字节的二进制表示形式为-108(-0x6C),因此以下内容具有相同的效果:

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

我的第一个答案是位移位,但第二个想法是,我认为使用outputstreams可能更好、更容易理解。我通常避免使用强制转换,但如果您不打算使用通用解决方案,我想这也没问题。:)

使用streams,通用解决方案:

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();
}
为了扭转这种局面:

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();
}
public static int fromByteArray(byte[] b) {
    ByteBuffer buf = ByteBuffer.wrap(b);
    return buf.getInt();
}

比约恩对使用流给出了一个很好的通用答案。您还可以使用
java.nio.ByteBuffer
执行同样的操作,这样代码会稍微少一些,您还可以控制输出的尾数(字节顺序)

要创建字节数组,请执行以下操作:

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

   sendData[0] = 0x26;
   sendData[1] = 0x94;
     }
}
public static byte[] toByteArray(int bits) {
    ByteBuffer buf = ByteBuffer.allocate(4);
    buf.putInt(bits);
    return buf.array();
}
要扭转这种局面:

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();
}
public static int fromByteArray(byte[] b) {
    ByteBuffer buf = ByteBuffer.wrap(b);
    return buf.getInt();
}

这会使我失去精度,不是吗?@Mark:这会让编译器清楚地知道你在做你想做的事情。0x94在一个字节的范围内,因此这里没有实际的精度损失。我认为一个字节的范围是从-128到127,0x94是148@Mark-0x94作为一个字节实际上不是148,而是-108。@Mark:嗯。。。否。从位看,字节的范围是0b00000000到0b11111111,0x94=0b10010100,这正好在其范围内。按位计算,“有符号字节”的概念没有任何意义。只有当你把一个8位的序列解释为一个整数时,它才开始清晰。。。你只需要两个。其余的都很简单。这是两个错误——不是因为所有的东西都有符号,而是因为0x94是一个int,不是一个字节,第二个char类型是无符号的,第三个——这是一个笑话吗?如果你只是在和那个家伙捣乱,那可能值得一个+1:)如果你用(字节)0x94向下转换是一个int,那么原版就可以了,因为它不适合一个字节
,因为字节是有符号的
。你是对的,字符是无符号的-但是,这是规则的例外,因为它不是
想要的
数字-JavaGods决定他们所有的数字都要有符号。你能把它当作字符串优化的数字吗?是的,你可以。它是否打算用作数字?否。
字符
类是否扩展了
数字
类?不。第三,不,这段代码不是开玩笑的,它是一种合法的方法,可以将任何int转换为字节数组,以准确地表示其位。我以前用它来创建TCP/IP数据包。我试过你的代码,效果很好。感谢您帮助初学者学习Java!请注意,在Java中,通常使用DataOutputStream(或其子类ObjectOutputStream)来完成通过线路发送的扁平化数据结构。无需每次都重新修改bittfidding:-)@meriton:更好的是,使用
java.nio.ByteBuffer
,它可以完成所有这一切,不必处理IOException,也可以控制endianness。您还可以使用java.nio.ByteBuffer通用地执行此操作,必要时还可以控制endianness。我已经为这种可能性添加了答案。要将有符号字节转换回其无符号整数形式,只需编写
b&0xff