Problem
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4215269
solution 1:
use Long.parseLong and do type conversion to int
why it works?
In Java language Specification 5.1, it gives:
A widening conversion of a signed integer value to an integral type T simply sign-extends the two's-complement representation of the integer value to fill the wider format. A widening conversion of a
char
to an integral type T zero-extends the representation of thechar
value to fill the wider format.
A narrowing conversion of a
char
to an integral type T likewise simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the resulting value to be a negative number, even thoughchar
s represent 16-bit unsigned integer values.
long -> int is a narrowing conversion. It only keep the lowest 32 oder bits. That's exactly what we want.
The two's complement of a binary number is defined as the value obtained by subtracting the number from a large power of two (specifically, from 2N for an N-bit two's complement). The two's complement of the number then behaves like the negative of the original number in most arithmetic, and it can coexist with positive numbers in a natural way.
A two's-complement system or two's-complement arithmetic is a system in which negative numbers are represented by the two's complement of the absolute value
A similar version with above but reveal the twp's-complement
Problem come again:
how to handle Long.toHexString
solution 2:
1. construct byte[] from hex code
2. use byte[] to long
explain:
1. why cast to (long) before shift
According JLS 5.6.2 Binary Numeric Promotion . when doing b[i] << (i*8) , both operands are converted to type int.
The int type only has 32 bits. If you shift more than this, it masked by the size of the type minus one. [Java programming language 9.2.5 Bit Manipulation Operators]
2. why b[i] + 256 when b[i] < 0 or b[i] & oxFF
According to the widening conversion in the previous section. When convert a byte to integer or long, the higher bits is extended by sign. So for b[i] < 0, the higher value is 1 while we want them to be 0.
solution 3:
avoid using Integer.toHexString , use Long.toString(value, 16) to get hex code.
You will get a '-' sign in front of the negative number which may be ugly, but it works."
Compare 3 solution:
- solution1 is a smart but limited to special case: integer
- solution2 is generic. It can be extends to Long
- solution3 is philosophy. When a problem occur, instead of finding a solution to fix it directly. Try to find another ways which achieve same target but do not this problem
That's how to we solve a problem:
Fix find a particular method to solve the problem. then try to extend it to generic case. At last, you need jump out the boxes, try any new approach to avoid the problem from the source