java converting int to short

两盒软妹~` 提交于 2019-12-11 17:15:33

问题


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. 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. This works fine till checksum value is less than 32767 thereafter i am getting negative values.

Thing is java does not have unsigned primitives, so i am not able to send values greater than max value of signed short allowed.

How can i do this, converting int to short and send over the network without worrying about truncation and signed & unsigned int.

Also on both the side i have java program running.

   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();
    }

回答1:


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(). This should give you the same numerical value as the server.




回答2:


char is an unsigned 16 bit type. In fact it's the only unsigned type in 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.

Bear in mind that bytes are signed.




回答3:


Firstly, Java int, short and byte types are all signed not unsigned. Secondly, when you cast a Java int to a short, etc you will get silent truncation.

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. For example, those "negative" 16bit checksums could be correct when interpreted by something expecting unsigned values.

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.)

EDIT I understand that you are calculating CRC-16. Since that can be computed by shifting and XORing, there should be no concerns about signed versus unsigned numbers during the calculation.

In short, you don't have anything to worry about.




回答4:


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. 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. 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.



来源:https://stackoverflow.com/questions/2485643/java-converting-int-to-short

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!