...
Noncompliant Code Example
Code Block | ||
---|---|---|
| ||
int a,b,result result = a/b; |
...
Code Block | ||
---|---|---|
| ||
if(a == Integer.MIN_VALUE) throw ArithmeticException; else result = --a; |
SHIFTING
The shift in java is quite different than in C\C++.
1) The right shift in java is an arithmetic shift while in C\C++ is implementation defined (logical or arithmetic)
2) In C\C++ if the value being left shifted is negative or the right hand operator of the shift operation is negative or greater than or equal to the width of the promoted left operand we have umdefined behaviour. This does not apply in Java since for the case of integer type it is masked with 0x1F and as a result we can always have a value that is modulo 31. When the value to be shifted (left-operand) is a long, only the last 6 bits of the right-hand operand are used to perform the shift. The actual size of the shift is the value of the right-hand operand masked by 63 (0x3D) Java Language Specification(§15.19 )
ie the shift distance is always between 0 and 63 (if shift value is greater than 64 shift is 64%value)
35 00000000 00000000 00000000 00100011
31 -> 0x1f 00000000 00000000 00000000 00011111
& -----------------------------------
Shift value 00000000 00000000 00000000 00000011 -> 3
So according to JLS
"At run time, shift operations are performed on the two's complement integer representation of the value of the left operand. The value of n<<s is nleft-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.The value of n>>s is n right-shifted s bit positions with sign-extension. The resulting value is
?n/2s?. For nonnegative values of n, this is equivalent to truncating integer division, as computed by the integer division operator /, by two to the power s."
3) There is a new operator in Java <<< that performs unsigned right shift
Example:
Code Block | ||
---|---|---|
| ||
int val = 2 <<-29;
int val = 2 << 35;
These both print 16 because they are transformed to 2<<3
|
Although we can not have undefined behaviour in Java we still have to ensure that we get the correct results. So we should explicitly check for ranges
Code Block | ||
---|---|---|
| ||
Operations Requiring Really Long Numbers
...