Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.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 使用ByteBuffer将n字节数组转换为整数_Java_Byte_Bytebuffer - Fatal编程技术网

Java 使用ByteBuffer将n字节数组转换为整数

Java 使用ByteBuffer将n字节数组转换为整数,java,byte,bytebuffer,Java,Byte,Bytebuffer,我需要将任意大小的字节数组转换为short/int/long 这意味着我可以接收3字节以转换为int: final byte[] bytes = { 0b0000, 0b0000, 0b1111 }; // 15 - big endian final int value = doConversion(bytes); 因此,我试图提出一个通用函数 ByteBuffer当数组的大小正好表示short、int、long值时,转换效果非常好。但是如果我有一个int表示为一个字节会怎么样呢 final

我需要将任意大小的字节数组转换为
short
/
int
/
long

这意味着我可以接收
3
字节以转换为
int

final byte[] bytes = { 0b0000, 0b0000, 0b1111 }; // 15 - big endian
final int value = doConversion(bytes);
因此,我试图提出一个通用函数


ByteBuffer
当数组的大小正好表示
short
int
long
值时,转换效果非常好。但是如果我有一个
int
表示为一个字节会怎么样呢

final byte[] bytes = { 0b1111 }; // 15
使用
ByteBuffer
将这样的字节数组转换为
int
似乎需要调整数组的大小并填充它。
负值会使事情变得更加复杂,因为填充需要使用最重要的位

是否有更简单的方法来完成此任务,或者我应该只使用自定义代码?
例如,在Kotlin中,使用扩展函数:

fun ByteArray.toShort(byteOrder: ByteOrder = LITTLE, signed: Boolean = true): Short =
    toInteger(Short.SIZE_BYTES, byteOrder, signed).toShort()

fun ByteArray.toInt(byteOrder: ByteOrder = LITTLE, signed: Boolean = true): Int =
    toInteger(Int.SIZE_BYTES, byteOrder, signed).toInt()

fun ByteArray.toLong(byteOrder: ByteOrder = LITTLE, signed: Boolean = true): Long =
    toInteger(Long.SIZE_BYTES, byteOrder, signed)

private fun ByteArray.toInteger(
     typeBytes: Int /* 2, 4, 8 */,
     byteOrder: ByteOrder /* little, big */, 
     signed: Boolean,
): Long {
    // Checks omitted...

    // If the byte array is bigger than the type bytes, it needs to be truncated
    val bytes =
        if (size > typeBytes) {
            if (byteOrder == LITTLE) {
                copyOf(typeBytes)
            } else {
                copyOfRange(size - typeBytes, size)
            }
        } else {
            copyOf()
        }

    val negative =
        signed && (this[if (byteOrder == LITTLE) bytes.size - 1 else 0]).toInt() and 0b1000000 != 0

    if (!negative) {
        return bytes.absoluteToLong(byteOrder)
    }

    // The number is stored as two's complement.
    // Thus we invert each byte and then sum 1 to obtain the absolute value
    for (i in bytes.indices) {
        bytes[i] = bytes[i].inv()
    }

    return -(bytes.absoluteToLong(byteOrder) + 1)
}

private fun ByteArray.absoluteToLong(byteOrder: ByteOrder): Long {
    var result = 0L
    var shift = 8 * (size - 1)
    val range =
        if (byteOrder == LITTLE) {
            size - 1 downTo 0
        } else {
            0 until size
        }

    for (i in range) {
        result = (this[i].toInt() and 0b11111111).toLong() shl shift or result
        shift -= 8
    }

    return result
}

BigInteger类有一个构造函数,对于这个用例很方便。例如:

byte[] bytes = { 0b1111 }; 
int value = new BigInteger(bytes).intValue(); 
它为您执行“符号扩展”:如果数组中的第一个字节值为负数,则最终结果为负数


它还提供了与其他数字类型(短、长等)一样检索值的方法。

谢谢!我假设接受的字节必须始终是big-endian。另外(可能是离题),无符号值呢?e、 g.255表示为单个字节。注意到更新。还可以添加如何考虑有符号/无符号值。e、 g.
byte[]bytes={(byte)0b11111111}//255作为单个字节
将使用
新的BigInteger(bytes).intValue()&0xFF
进行转换。正确,它采用大端顺序。至于unsigned,我还没有测试它,但是添加一个零字节作为填充应该可以,但是应用这两个补码只会改变符号。例如,
new BigInteger(新字节[]{(字节)0b11111111}/*255*/).intValue()
将返回
-1
,应用2的补码将使其成为
1
。也许我误解了你的意思哦,好吧,我看到你修改过了。没问题!
byte[] bytes = { 0b1111 }; 
int value = new BigInteger(bytes).intValue();