简体   繁体   English

java将int转换为short

[英]java converting int to short

I am calculating 16 bit checksum on my data which i need to send to server where it has to recalculate and match with the provided checksum. 我正在对我的数据计算16位校验和,我需要将该数据发送到服务器,服务器必须重新计算并与提供的校验和匹配。 Checksum value that i am getting is in int but i have only 2 bytes for sending the value.So i am casting int to short while calling shortToBytes method. 我得到的校验和值是int但我只有2个字节用于发送该值。所以我在调用shortToBytes方法时将intshort This works fine till checksum value is less than 32767 thereafter i am getting negative values. 直到校验和值小于32767,然后我得到负值,这才能正常工作。

Thing is java does not have unsigned primitives, so i am not able to send values greater than max value of signed short allowed. 事情是Java没有未签名的原语,所以我不能发送大于允许的有符号的short最大值的值。

How can i do this, converting int to short and send over the network without worrying about truncation and signed & unsigned int. 我该怎么做,将int转换为short并通过网络发送,而不必担心截断和有符号和无符号int。

Also on both the side i have java program running. 同样在双方我都在运行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();
    }

Firstly, Java int , short and byte types are all signed not unsigned. 首先,Java intshortbyte类型都是有符号的,而不是无符号的。 Secondly, when you cast a Java int to a short , etc you will get silent truncation. 其次,当您将Java int转换为short ,etc会被静默截断。

Whether this matters depends on the nature of the checksum algorithm. 这是否重要取决于校验和算法的性质。 If it is a simple sum, or a bitwise algorithm there is a good chance that the algorithm is just fine when implemented using Java signed integers. 如果是简单的总和或按位算法,则很有可能在使用Java有符号整数实现时该算法就很好。 For example, those "negative" 16bit checksums could be correct when interpreted by something expecting unsigned values. 例如,那些“负”的16位校验和在被期望无符号值的东西解释时可能是正确的。

On the other hand, the semantic of multiplication and division are such that signed and unsigned flavors have to be handled separately. 另一方面,乘法和除法的语义使得必须分别处理有符号和无符号形式。 (At least, that's what I infer from the unscientific approach of looking at the x86 instruction set ... which has separate instructions for signed versus unsigned multiplication and division.) (至少,这是我从查看x86指令集的不科学方法中推断出来的……它具有用于有符号和无符号乘法与除法的单独指令。)

EDIT I understand that you are calculating CRC-16. 编辑我了解您正在计算CRC-16。 Since that can be computed by shifting and XORing, there should be no concerns about signed versus unsigned numbers during the calculation. 由于可以通过移位和XOR运算来计算,因此在计算过程中不必担心有符号数与无符号数。

In short, you don't have anything to worry about. 简而言之,您无需担心。

char is an unsigned 16 bit type. char是一个无符号的16位类型。 In fact it's the only unsigned type in Java. 实际上,它是Java中唯一的无符号类型。 You can use it for calculating the checksum and then use a ByteBuffer to get the bytes or simply use bitwise and and right shifting to get the bytes. 您可以使用它来计算校验和,然后使用ByteBuffer来获取字节,或者仅使用按位和右移来获取字节。

Bear in mind that byte s are signed. 请记住, byte s是带符号的。

You are still getting the same bit value as the server. 您仍然获得与服务器相同的位值。 So, to see the right numerical value replace the ByteBuffer.wrap(baValue).getShort() to a ByteBuffer.wrap(baValue).getInt() . 因此,要查看正确的数值,请将ByteBuffer.wrap(baValue).getShort()替换为ByteBuffer.wrap(baValue).getInt() This should give you the same numerical value as the server. 这应该为您提供与服务器相同的数值。

When you say that you are getting negative values, I assume you mean when you read the 16 bit value and convert it to an integer. 当您说得到负值时,我假设您的意思是当您读取16位值并将其转换为整数时。 The reason for this is that sign extension causes the most significant bit (which is a 1) to be replicated when the short is widened to an int . 这样做的原因是,在将short扩展为int时,符号扩展会导致最高有效位(即1)被复制。 The simple workaround is to bitwise-and the reconstructed integer with 0xFFFF , which will ensure that only the least signficant 16 bits are non-zero. 最简单的解决方法是按位进行-并使用0xFFFF重构整数,这将确保只有最低有效位的16位为非零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM