简体   繁体   English

在 java 中将 int 转换为长度为 2 的字节数组的答案存在冲突

[英]Conflicting answers on converting int to byte array of length 2 in java

I'm trying to convert integers into 2 bytes, but I'm seeing some conflicting answers online between:我正在尝试将整数转换为 2 个字节,但我在网上看到一些相互矛盾的答案:

a[0] = (byte)(theInt & 0xFF);
a[1] = (byte)((theInt >>> 8) & 0xFF);

and

a[0] = (byte)((theInt >>> 8) & 0xFF);
a[1] = (byte)(theInt & 0xFF);

The first seems to be the more common answer ( How do I split an integer into 2 byte binary? ).第一个似乎是更常见的答案( 如何将 integer 拆分为 2 字节二进制? )。

However, for me personally, the second seems to be working better.但是,就我个人而言,第二个似乎效果更好。 If I set theInt = 10000 , I get the desired {27, 10} .如果我设置theInt = 10000 ,我会得到所需的{27, 10} But for the first method I get the reverse {10, 27} .但是对于第一种方法,我得到了相反的{10, 27}

So is there any risk in me going against the popular answer and using the first method?那么我反对流行的答案并使用第一种方法有什么风险吗? Am I missing something?我错过了什么吗? Thanks谢谢

The concept of how to sequence the bytes of a multibyte numeric value (such as the 16-bit value you're converting here) is called 'endianness'.如何对多字节数值(例如您在此处转换的 16 位值)的字节进行排序的概念称为“字节顺序”。

Little Endian is the term for 'send the least significant data first', that'd be the first snippet. Little Endian 是“首先发送最不重要的数据”的术语,这将是第一个片段。 (send '10' first, then '27'). (先发送“10”,然后发送“27”)。

Big Endian is the term for 'send the most significant data first', so, the second snippet. Big Endian 是“首先发送最重要的数据”的术语,因此是第二个片段。

You'd think Big Endian is sensible (it matches how we humans write things, for example, and matches how we think about bits within bytes too; 128 is, in bits, '10000000' - the most significant data is written first, after all), and Little Endian is insane, and wonder why the concept of LE even exists.您会认为 Big Endian 是明智的(例如,它符合我们人类编写事物的方式,也符合我们对字节内位的看法;128 以位为单位,是“10000000”——首先写入最重要的数据,然后all),而 Little Endian 是疯了,想知道为什么 LE 的概念甚至存在。

The primary reason for that is that the intel CPU architecture is Little Endian, and that is very popular CPU architecture.主要原因是intel CPU架构是Little Endian,是非常流行的CPU架构。 If you first write 32-bit int with value '1' to some memory address, and then read it back out byte for byte, then you get, in order: '1', '0', '0', and '0' out: Little Endian - the least significant byte is written first.如果您首先将值为 '1' 的 32 位 int 写入某个 memory 地址,然后逐个字节地读取它,那么您将按顺序获得:'1'、'0'、'0' 和 '0 ' out: Little Endian - 首先写入最低有效字节。 These days with pipelines, micro architecture and who knows what asking an intel processor to write it out in BE form is probably not really slower, but it is more machinecode, and certainly in the past, significantly slower.如今,有了管道、微架构,谁知道要求英特尔处理器以 BE 形式写出它可能并没有真正慢,但它更多的是机器代码,当然在过去,速度要慢得多。 Thus, if you were trying to squeeze max performance out 2 machines talking to each other with a really really fast pipe in between and both machines had intel chips, it'd go faster if you send in little endian: That way both CPUs are just copying, that's all, vs. sending in BE which would require the sender chip to swap bytes 1/4 and 2/3 around for every int it sends, and the receiver chip to apply the same conversion, wasting cycles.因此,如果您试图在两台机器之间使用非常快的 pipe 相互通信,并且两台机器都有英特尔芯片,那么如果您发送小端序,那么 go 会更快:这样两个 CPU 都只是复制,仅此而已,而在 BE 中发送则需要发送器芯片为它发送的每个 int 交换字节 1/4 和 2/3,并且接收器芯片应用相同的转换,浪费周期。

Thus, from time to time, you find a protocol defined to be LE.因此,有时您会发现一个协议被定义为 LE。 That's.. short sighted in this world of varied hardware where you're just as likely to end up having both sender and receiver eg by an ARM chip, or worse, for 10 chips to be involved (bunch of packet-inspecting routers in between), probably all of them BE.那是..在这个拥有各种硬件的世界中目光短浅,您最终可能会同时拥有发送器和接收器,例如通过 ARM 芯片,或者更糟糕的是,涉及 10 个芯片(中间有一堆数据包检查路由器),可能所有这些都是。 But now you know why LE as a concept does exist.但是现在您知道为什么 LE 作为一个概念确实存在。

Because of this modern age of varied hardware, and because most other CPUs are big endian, almost all network protocols are generally defined to be Big Endian.由于现代硬件种类繁多,而且大多数其他 CPU 都是大端,几乎所有的网络协议通常都被定义为大端。 java is generally Big Endian as well (most APIs, such as IntBuffer and co, let you pick which endian-ness you want, but where it is not available, or where defaults are concerned, it's big endian). java 通常也是 Big Endian(大多数 API,例如IntBuffer和 co,让您选择您想要的 endian-ness,但是在它不可用的地方,或者在涉及默认值的地方,它是 big endian)。 Formats like UTF-8 are also defined as being big-endian. UTF-8 等格式也被定义为大端。 When in doubt, Big Endian is far more likely to be the intended ordering than LE would be.当有疑问时,Big Endian 比 LE 更有可能成为预期的顺序。

The ARM chips that run android devices are also Big Endian.运行 android 器件的 ARM 芯片也是大端。

Thus: Just use Big Endian (second snippet).因此:只需使用 Big Endian(第二个片段)。

That just leaves one mystery: Why is the accepted answer to your linked question the 'weird' one (Little Endian), and why does it get that many upvotes even though it doesn't highlight this?这只留下了一个谜:为什么您的链接问题的公认答案是“奇怪”的答案(Little Endian),为什么即使它没有突出这一点,它也会得到这么多的支持? The question even specifically asks for Big Endian (it describes it, doesn't use the term of art for it, but nevertheless, it describes BE).这个问题甚至专门询问 Big Endian(它描述了它,没有使用艺术术语,但是它描述了 BE)。

I don't know.我不知道。 It's a stupid answer with a checkbox and 68 votes.这是一个带有复选框和 68 票的愚蠢答案。 Mysterious.神秘。

I did my part, and downvoted it.我尽了自己的一份力量,并否决了它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM