在Java中将字节转换为整数

8

我需要在Java代码中将2个字节(2的补码)转换为int类型。如何实现?

toInt(byte hb, byte lb)
{
}

你是想自己实现它,因为你有老师布置的特定任务或其他原因吗? 还是你只是想使用内置的Java类? - TheChange
如果内置的Java类有将2个字节转换为整数的方法,请告诉我。 - user121196
2
可能是将4个字节转换为整数的重复问题。 - OscarRyz
1
也许考虑一下为什么要传递原始字节?你可能可以通过去SO轻松解决这个问题,但这表明了更大的问题。这个int是什么?为什么必须是字节?在另一种形式中持久化这些数据有哪些替代方案? - corsiKa
@glowcoder:比你想象的更普遍。 - Yann Ramin
5个回答

15
return ((int)hb << 8) | ((int)lb & 0xFF);

正确的操作方法在所有情况下都留给学生自己练习。


6
这些铸件都是多余的。 - Mark Peters
1
需要注意的是,此解决方案仅适用于有符号短整数表示,并且不适合解码使用无符号格式表示端口的TCP头。 - Andras Balázs Lajtha
2
如果您不想失去精度,需要使用 "& 0xFF" 进行操作。像这样:return (hb & 0xFF) << 8 | (lb & 0xFF); - j2gl

11

您也可以使用 ByteBuffer 类:

public int toInt(byte hb, byte lb) {
    ByteBuffer bb = ByteBuffer.wrap(new byte[] {hb, lb});
    return bb.getShort(); // Implicitly widened to an int per JVM spec.
}

如果你需要大量解码数据,这个类可能会有所帮助。


但是如果这两个字节是用二进制补码表示的,那么hb的第一个字节不就成了符号位吗?所以你的 new byte[]{a,b,c,d} 应该是 a= hb & 0x80; b=0; c= hb & 0x7F; d= lb;?我可能有些偏离主题了。 - corsiKa
很好的提醒,hb 的第一个比特应该被拉到 a 左侧,所以我的解决方案可能不是他要找的。我只是想指出 ByteBuffer 类... - maerics
使用getShort代替getInt。当你将得到的short强制转换为int时,它将被符号扩展以得到正确的结果。 - finnw
@finnw:好主意,为什么我没想到呢?=) - maerics

1

使用方法:

public class Test {

    public static void main(String[] args) {
        byte[] b = new byte[] { -83, 0, 0, 0 };

        int i = GattUtils.getIntValue(b, GattUtils.FORMAT_UINT32, 0);

        System.out.println(i); //will print 173
    }


public class GattUtils {
    public static final long leastSigBits = 0x800000805f9b34fbL;

    public static final int FIRST_BITMASK = 0x01;
    public static final int SECOND_BITMASK = FIRST_BITMASK << 1;
    public static final int THIRD_BITMASK = FIRST_BITMASK << 2;
    public static final int FOURTH_BITMASK = FIRST_BITMASK << 3;
    public static final int FIFTH_BITMASK = FIRST_BITMASK << 4;
    public static final int SIXTH_BITMASK = FIRST_BITMASK << 5;
    public static final int SEVENTH_BITMASK = FIRST_BITMASK << 6;
    public static final int EIGTH_BITMASK = FIRST_BITMASK << 7;

    public static final int FORMAT_UINT8 = 17;
    public static final int FORMAT_UINT16 = 18;
    public static final int FORMAT_UINT32 = 20;
    public static final int FORMAT_SINT8 = 33;
    public static final int FORMAT_SINT16 = 34;
    public static final int FORMAT_SINT32 = 36;
    public static final int FORMAT_SFLOAT = 50;
    public static final int FORMAT_FLOAT = 52;

    public static UUID toUuid(String uuidString) {
        return UUID.fromString(uuidString);
    }

    public static UUID toUuid(long assignedNumber) {
        return new UUID((assignedNumber << 32) | 0x1000, leastSigBits);
    }

    public static String toUuid128(long assignedNumber) {
        return toUuid(assignedNumber).toString();
    }

    public static String toUuid16(int assignedNumber) {
        return Integer.toHexString(assignedNumber);
    }

    public static Integer getIntValue(byte[] value, int format, int position) {
        if (value == null)
            return null;
        if (position + (format & 0xF) > value.length)
            return null;
        switch (format) {
        case FORMAT_UINT8:
            return Integer.valueOf(value[position] & 0xFF);
        case FORMAT_UINT16:
            return Integer.valueOf(add(value[position], value[(position + 1)]));
        case FORMAT_UINT32:
            return Integer.valueOf(add(value[position], value[(position + 1)], value[(position + 2)], value[(position + 3)]));
        case FORMAT_SINT8:
            return Integer.valueOf(signed(value[position] & 0xFF, 8));
        case FORMAT_SINT16:
            return Integer.valueOf(signed(add(value[position], value[(position + 1)]), 16));
        case FORMAT_SINT32:
            return Integer.valueOf(signed(add(value[position], value[(position + 1)], value[(position + 2)], value[(position + 3)]), 32));
        }
        return null;
    }

    public static Float getFloatValue(byte[] value, int format, int position) {
        if (value == null)
            return null;
        if (position + (format & 0xF) > value.length)
            return null;
        int i;
        int mantissa;
        int exponent;
        switch (format) {
        case FORMAT_SFLOAT:
            i = value[(position + 1)];
            position = value[position];
            mantissa = signed((position & 0xFF) + ((i & 0xFF & 0xF) << 8), 12);
            exponent = signed((i & 0xFF) >> 4, 4);
            return Float.valueOf((float) (mantissa * Math.pow(10.0D, exponent)));
        case FORMAT_FLOAT:
            exponent = value[(position + 3)];
            mantissa = value[(position + 2)];
            i = value[(position + 1)];
            position = value[position];
            return Float.valueOf((float) ((format = signed((position & 0xFF) + ((i & 0xFF) << 8) + ((mantissa & 0xFF) << 16), 24)) * Math.pow(10.0D, exponent)));
        }
        return null;
    }

    public static String getStringValue(byte[] value, int position) {
        if (value == null)
            return null;
        if (position > value.length)
            return null;
        byte[] arrayOfByte = new byte[value.length - position];
        for (int i = 0; i != value.length - position; i++) {
            arrayOfByte[i] = value[(position + i)];
        }
        return new String(arrayOfByte);
    }

    private static int add(byte byte1, byte byte2) {
        return (byte1 & 0xFF) + ((byte2 & 0xFF) << 8);
    }

    private static int add(byte byte1, byte byte2, byte byte3, byte byte4) {
        return (byte1 & 0xFF) + ((byte2 & 0xFF) << 8) + ((byte3 & 0xFF) << 16) + ((byte4 & 0xFF) << 24);
    }

    private static int signed(int value, int length) {
        if ((value & 1 << length - 1) != 0)
            value = -1 * ((1 << length - 1) - (value & (1 << length - 1) - 1));
        return value;
    }

    /**
     * Convert hex byte array from motorola API to byte array.
     * 
     * @param hexByteArray
     * @return
     */
    public static byte[] hexByteArrayToByteArray(byte[] hexByteArray) {
        return hexStringToByteArray(new String(hexByteArray));
    }

    /**
     * Convert string from motorola API to a byte array.
     * 
     * @param hexString
     * @return
     */
    public static byte[] hexStringToByteArray(String hexString) {
        int len = hexString.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i + 1), 16));
        }
        return data;
    }
}

-1

对于那些正在寻找小端值的人:

int num = ByteBuffer.wrap(b, 0, 2).order(LITTLE_ENDIAN).char.toInt()

-1
public int toInt(byte hb, byte lb)
{
    return ((int)hb)<<8 + lb;
}

这个答案和theatrus的答案一样吗? - user121196
修改了答案,解决方案是在<<运算符周围添加括号,希望它很快被批准,其他人不会花费一天的时间调试使用此片段的代码 :) - Andras Balázs Lajtha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接