【问题标题】:java: fastest way of converting a bye array byte [1000] to array int[500]java:将字节数组byte [1000]转换为数组int [500]的最快方法
【发布时间】:2012-01-19 19:02:35
【问题描述】:

目标是将每对字节转换为单个无符号 16 位 int。 在 C 中我会定义一个 16 位 unsinged int 指针的数组 [500] 并将其指向字节数组,但在 java 中我不知道这样的捷径。 我知道在 Java 中除了 char 之外没有 16 位数据类型,但这不是问题。我们只需要将每两个连续的两个字节复制到一个整数数组的单个 int 中。因此整数数组包含的 int 值范围为 0 到 65535 (2^16-1)。

【问题讨论】:

  • @anubhava - short 确实是 16 位数据类型。我认为 OP 的问题在于它始终是 Java 中的有符号数量。没有像 unsigned 短这样的东西。

标签: java arrays casting bytearray unsigned-integer


【解决方案1】:

您可以使用 ByteBuffer 来避免经常出错的移位和屏蔽。 (也有签名与未签名)

ByteBuffer bb = ByteBuffer.wrap(bytes);
bb.order(ByteOrder.BIG_ENDIAN);  // or LITTLE_ENDIAN
short[] shorts = new short[bytes.length/2];
for (int i=0; i<shorts.length; i++)
   shorts[i] = bb.getShort();

注意——如果你真的想要一个“无符号短”,java中没有这样的东西,所以你的数组必须是整数。你会使用转换

for (int i=0; i<intArray.length; i++) {
   short s = bb.getShort();
   intArray[i] = s & 0xFFFF; // mask off all the high order bits
}

【讨论】:

    【解决方案2】:

    我认为在 Java 中没有像在 C 中可以做的别名那样好的技巧。你将不得不手动完成:

    public int[] pack(byte[] bytes) {
        int n = bytes.length >> 1;
        int[] packed = new int[n];
        for (int i = 0; i < n; ++i) {
            int i2 = i << 1;
            int b1 = bytes[i2] & 0xff;
            int b2 = bytes[i2 + 1] & 0xff;
            packed[i] = (b1 << 8) | b2;
        }
        return packed;
    }
    

    (这可能会加快一点速度,但对于 1,000 个元素可能不值得,除非它做了很多。)请注意,从 byteint 的提升需要一些额外的工作来处理不需要的符号扩展。

    【讨论】:

    • 谢谢,没错,但是当我们将每两个字节转换为 32 位有符号位时,从字节到整数的提升无需担心不需要的符号扩展,因为要转换的最大值为 56635到 int32。
    • @Cgraphics 错误。问题是当设置字节的最高位时,值为负。升级到int 是通过将符号位向左扩展来完成的,因此int 的值最终也会为负。在某些时候,必须做一些掩蔽。因此,例如,((byte)0x80) &lt;&lt; 8not 0x00008000;它是0xffff8000
    【解决方案3】:

    Java 中没有真正的无符号 16 位整数类型 -- 除了 也许 char,如果你觉得这门语言在辱骂的话。也就是说,现在是使用流行的 Guava 实用程序库的好时机:

    public short[] pack(byte[] bytes) {
       short[] result = new short[bytes.length / 2];
       for (int i = 0; i < bytes.length; i += 2) {
         result[i/2] = Shorts.fromBytes(bytes[i], bytes[i+1]);
       }
    }
    

    如果你真的对性能很挑剔,你可以添加一个单独的计数器或使用右移而不是除法,但这很简单。

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 2013-06-25
      • 2014-03-05
      • 1970-01-01
      • 2017-08-22
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多