【问题标题】:Convert short to byte[] in Java在 Java 中将 short 转换为 byte[]
【发布时间】:2011-01-12 10:02:54
【问题描述】:

如何将short(2 字节)转换为 Java 中的字节数组,例如

short x = 233;
byte[] ret = new byte[2];

...

应该是这样的。但不确定。

((0xFF << 8) & x) >> 0;

编辑:

你也可以使用:

java.nio.ByteOrder.nativeOrder();

发现获取本机位顺序是大还是小。此外,以下代码取自java.io.Bits

  • 字节(数组/偏移)到布尔值
  • 字节数组转字符
  • 短字节数组
  • 字节数组到int
  • 要浮动的字节数组
  • 长字节数组
  • 字节数组加倍

反之亦然。

【问题讨论】:

标签: java byte short


【解决方案1】:
ret[0] = (byte)(x & 0xff);
ret[1] = (byte)((x >> 8) & 0xff);

【讨论】:

  • 不过,这是小端。网络字节序为大端:'byte[] arr=new byte[]{(byte)((x>>8)&0xFF),(byte)(x&0xFF)};
  • 这也可以byte[] arr=new byte[]{(byte)(x&gt;&gt;&gt;8),(byte)(x&amp;0xFF)}
  • 我可以在这里问一下,如果将 short 或 int 转换为字节只会占用 LSB,为什么需要屏蔽?谢谢
  • 屏蔽是多余的。无论如何,转换为字节会截断高位,因此将它们屏蔽掉是完全没有意义的。
  • 是的——虽然它澄清了意图。当转换为较小的类型时,我通常建议 i) 如果您确定不会发生截断,则提前断言,或者 ii) 显式屏蔽。这种策略避免了来自大量分析/查找错误工具的误报。
【解决方案2】:

一个更清洁但效率低得多的解决方案是:

ByteBuffer buffer = ByteBuffer.allocate(2);
buffer.putShort(value);
return buffer.array();

当您将来必须进行更复杂的字节转换时,请记住这一点。 ByteBuffers 非常强大。

【讨论】:

  • @abimelex,是的,这是必要的。最初,您在位置 0、1 处写入 2 个字节。如果您不这样做 buffer.flip(),则 buffer.array() 将从位置 2 开始读取 byte[]buffer.flip() 将位置设置为 0,将限制设置为 2,因此您最终会从正确位置开始的大小为 2 的数组。查看 Javadoc:docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html#flip()
  • 我们谈论的效率有多低?
  • @Barodapride:根据我自己的测试,我的回答比stackoverflow.com/a/2188682/14731 慢了6.8 倍。也就是说,大多数时候ByteBuffer 会“足够好”,而且它肯定更具可读性。意思是,只要分析器说它不是瓶颈,ByteBuffer 是否慢了一百万倍都没关系。
  • 我为实用方法做了一个单行:return ByteBuffer.allocate(2).putShort(shortValue).array();
  • 过于语义化:ByteBuffer.allocate( Short.BYTES ).putShort(shortValue).array();
【解决方案3】:

更有效的替代方案:

    // Little Endian
    ret[0] = (byte) x;
    ret[1] = (byte) (x >> 8);

    // Big Endian
    ret[0] = (byte) (x >> 8);
    ret[1] = (byte) x;

【讨论】:

  • 不应该反过来吗? IE。第一个是小端,第二个是大端。
  • 最低有效字节不是需要&amp; 0xFF 吗?
  • @bvdb:不需要用 0xFF 进行位掩码,因为一个字节已经是 8 位了。
  • @David 谢谢,仔细检查并确认。 :)
【解决方案4】:

想通了,它的:

public static byte[] toBytes(short s) {
    return new byte[]{(byte)(s & 0x00FF),(byte)((s & 0xFF00)>>8)};
}

【讨论】:

    【解决方案5】:

    Kotlin 中的短字节转换方法对我有用:

     fun toBytes(s: Short): ByteArray {
        return byteArrayOf((s.toInt() and 0x00FF).toByte(), ((s.toInt() and 0xFF00) shr (8)).toByte())
    }
    

    【讨论】:

    • 这个问题被标记为 Java,而不是 Kotlin。
    • @Gili 我知道,但这经常被 Android 开发者女巫使用 Kotlin 所寻找
    • 第二。 @SergBurlaka 你应该单独发表一篇文章并自己回答以获得加分,这样更多的 Kotlin 开发人员会看到你的回答。
    【解决方案6】:

    这取决于你想如何表示它:

    • 大端还是小端?这将决定您将字节放入的顺序。

    • 您想使用 2 的补码还是其他方式来表示负数?您应该使用与 java 中的 short 范围相同的方案来进行 1 对 1 映射。

    对于大端,转换应遵循以下原则: ret[0] = x/256; ret[1] = x%256;

    【讨论】:

      【解决方案7】:

      这里提到了几种方法。但是哪一个是最好的?以下是一些证明以下 3 种方法对于 short 的所有值产生相同的输出

        // loops through all the values of a Short
        short i = Short.MIN_VALUE;
        do
        {
          // method 1: A SIMPLE SHIFT
          byte a1 = (byte) (i >> 8);
          byte a2 = (byte) i;
      
          // method 2: AN UNSIGNED SHIFT
          byte b1 = (byte) (i >>> 8);
          byte b2 = (byte) i;
      
          // method 3: SHIFT AND MASK
          byte c1 = (byte) (i >> 8 & 0xFF);
          byte c2 = (byte) (i & 0xFF);
      
          if (a1 != b1 || a1 != c1 ||
              a2 != b2 || a2 != c2)
          {
            // this point is never reached !!
          }
        } while (i++ != Short.MAX_VALUE);
      

      结论:少即是多?

      byte b1 = (byte) (s >> 8);
      byte b2 = (byte) s;
      

      (正如其他答案所提到的,请注意LE/BE)。

      【讨论】:

        【解决方案8】:
        public short bytesToShort(byte[] bytes) {
             return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
        }
        
        public byte[] shortToBytes(short value) {
            byte[] returnByteArray = new byte[2];
            returnByteArray[0] = (byte) (value & 0xff);
            returnByteArray[1] = (byte) ((value >>> 8) & 0xff);
            return returnByteArray;
        }
        

        【讨论】:

          【解决方案9】:

          字节短

          short x=17000;    
          byte res[]=new byte[2];    
          res[i]= (byte)(((short)(x>>7)) & ((short)0x7f) | 0x80 );    
          res[i+1]= (byte)((x & ((short)0x7f)));
          

          字节变短

          short x=(short)(128*((byte)(res[i] &(byte)0x7f))+res[i+1]);
          

          【讨论】:

            猜你喜欢
            • 2012-12-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-04-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多