java将int转换为short

时间:2010-03-21 02:29:31

标签: java truncate unsigned-long-long-int

我正在计算我的数据的16位校验和,我需要将其发送到服务器,它必须重新计算并与提供的校验和匹配。我得到的校验和值是int,但是我只有2个字节用于发送值。所以我在调用int方法时将short强制转换为shortToBytes。这工作正常,直到校验和值小于32767,此后我得到负值。

事情是java没有无符号的原语,所以我无法发送大于允许的签名short的最大值的值。

我该怎么做,将int转换为short并通过网络发送而不用担心截断和签名& unsigned int。

另外,我也有java程序在运行。

   private byte[] shortToBytes(short sh) {
        byte[] baValue = new byte[2];
        ByteBuffer buf = ByteBuffer.wrap(baValue);
        return buf.putShort(sh).array();
    }

    private short bytesToShort(byte[] buf, int offset) {
        byte[] baValue = new byte[2];
        System.arraycopy(buf, offset, baValue, 0, 2);
        return ByteBuffer.wrap(baValue).getShort();
    }

4 个答案:

答案 0 :(得分:1)

首先,Java intshortbyte类型都是未签名的签名。其次,当您将Java int转换为short等时,您将获得静默截断。

这是否重要取决于校验和算法的性质。如果它是一个简单的求和或按位算法,那么当使用Java有符号整数实现时,该算法很可能很好。例如,那些“负”16位校验和在被期望无符号值的东西解释时可能是正确的。

另一方面,乘法和除法的语义是必须单独处理有符号和无符号的风格。 (至少,这是我从查看x86指令集的不科学方法推断出来的......它有单独的有符号与无符号乘法和除法的指令。)

编辑我知道您正在计算CRC-16。由于可以通过移位和异或来计算,因此在计算过程中不应该考虑有符号和无符号数。

简而言之,您无需担心。

答案 1 :(得分:1)

char是无符号16位类型。实际上它是Java中唯一的无符号类型。您可以使用它来计算校验和,然后使用ByteBuffer来获取字节,或者只使用按位和右移来获取字节。

请记住byte已签名。

答案 2 :(得分:1)

您仍然获得与服务器相同的位值。因此,要查看正确的数值,请将ByteBuffer.wrap(baValue).getShort()替换为ByteBuffer.wrap(baValue).getInt()。这应该给你与服务器相同的数值。

答案 3 :(得分:0)

当你说你得到负值时,我认为你的意思是当你读取16位值并将其转换为整数时。原因是当short扩展为int时,符号扩展会导致最高位(即1)被复制。简单的解决方法是按位和重建的0xFFFF整数,这将确保只有最不重要的16位非零。