Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The shift operators in Java have the following properties, according to The Java Language Specification (JLS), §15.19, "Shift Operators" [JLS 20052015]:

  • The >> right shift is an arithmetic shift; the >>> right shift is a logical shift.
  • The types boolean, float, and double cannot use the bit-shifting operators.
  • When the value to be shifted is of type int, only the five lowest-order bits of the right-hand operand are used as the shift distance. That is, the shift distance is the value of the right-hand operand masked by 31 (0x1F). The shift distance actually used is consequently always in the range 0 to 31, inclusive.
  • When the value to be shifted (left operand) is type long, only the last 6 bits of the right-hand operand are used to perform the shift. The shift distance is the value of the right-hand operand masked by 63 (0x3F). The shift distance actually used is consequently always in the range 0 to 63, inclusive.

...

Arithmetic vs. Logical Shift

The JLS§15.19 [JLS 20052015], defines the behavior of the arithmetic shift operator as follows:

The value of n>>s n>>s is n right-shifted s bit positions with sign-extension. The resulting value is floor(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.

The JLS also defines the behavior of the logical shift operator:

The value of n>>>s n >>> s is n right-shifted s bit positions with zero-extension, where:

  • . If n is positive, then the result is the same as that of n>>s; if n >> s.

  • If n is negative and the type of the left-hand operand is int, then the result is equal to that of the expression (n>>sn >> s) + (2<<~s) if 2 << ~s).

  • If n is negative and the type of the left-hand operand is intlong, and to then the result is equal to that of the expression (n>>sn >> s) + (2L<<~s) if the type of the left-hand operand is long. 2L << ~s).

The added term (2<<~s2 << ~s) or (2L<<~s2L << ~s) cancels out the propagated sign bit.

(Note that, because of the implicit masking of the right-hand operand of a shift operator, ~s ~s as a shift distance is equivalent to 31-s when shifting an int value and to 63-s when shifting a long value.)

Never use the arithmetic shift operator when the logical shift operator is required.

...

Code Block
bgColor#ffcccc
static int countOneBits(long value) {
  int bits = 0;
  while (value != 0) {
    bits += value & 1L;
    value >>= 1; // Signed right- shift, by one
  }
  return bits;
}

...

In this noncompliant code example, the programmer intends to shift a byte value two bits to the right (with zero fill). However, the JLS specifies that the left operand must be promoted to either type int or type long (int, in this case); this promotion performs sign extension. Because of the promotion, the result of the shift for negative input values will be a large positive number, and the programmer could find this result surprising.

Code Block
bgColor#ffcccc
byte b = /* Initialize */;
int result = b >>> 2;

...

This noncompliant code example tries to shift the value -1 by increasing the value of i until, after 32 iterations, the programmer believes the result would become 0. The loop actually never terminates because an attempt to shift a value of type int by 32 bits results in the original value (that is, −1) rather than the expected value 0 [Bloch 2005] . This is because only the least significant 5 bits of i are considered when the shift occurs, and when i reaches the value 32, the 5 least significant bits have the value 0.

...

Incorrect use of shift operators can lead to unanticipated results, causing erratic control flow or unanticipated program behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

NUM14-J

Low

Probable

Medium

P4

L3

Automated Detection

...

Tool

Version

Checker

Description

PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V6034

Related Guidelines

Bibliography

...


...

Image Modified Image Modified Image Modified