SDA SE Wiki

Software Engineering for Smart Data Analytics & Smart Data Analytics for Software Engineering

User Tools

Site Tools


This page illustrates how new pages that you created in this namespace will be initialized.

The italic text indicates what you should do to fill in the template.

Bug Cor12

Inspired by

Original Description

“The code performs shift of a 32 bit int by a constant amount outside the range -31..31. The effect of this is to use the lower 5 bits of the integer value to decide how much to shift by (e.g., shifting by 40 bits is the same as shifting by 8 bits, and shifting by 32 bits is the same as shifting by zero bits). This probably isn't what was expected, and it is at least confusing. ” – 2013-10-13

Detailed Description

Java offers three kind of bit shift operators: > >, < <, > > > (signed right shift, signed left shift and unsigned right shift). These operators can be applied to a 32bit Integer to shift it by a constant in the preferred direction. The problem is that in Java the constant is processed before shifting. To the absolute value the modulo 32 operation is applied. This might be quite confusing since it leads to different shifting offsets than intended. e.g. shifting by 32 equals 32%32=0 and by 40 equals 40%32=8.

The background is that every Integer value is represented by a bit pattern which corresponds to the binary representation of the int value. The leftmost (highest) bit of a (signed) Integer is the sign. 0 means plus and 1 minus. The lowest bit corresponds to 2^0 and the 31st bit to 2^31. Hence the (signed) 32bit Integer has a range of [-2^31, 2^31-1]. If the sign is minus, the stored absolute value equals the complement (inverted bits) plus 1. By shifting to the left or right we simply move the bit pattern. > > and < < take the sign into account by filling up the pattern appropriately, while > > > doesn't.

Overview: example 1110 (-2 as a signed 4bit Integer)

1110 < < 1 is 1100 (-4 as a signed 4bit Integer)

1110 > > 1 is 1111 (-1 as a signed 4bit Integer)

1110 > > > 1 is 0111 (7 as a signed 4bit Integer)

Sample Problem Scenario

<code Java> class ICAST_BAD_SHIFT_AMOUNT {

 public static void main(String[] args){
int val = -8;

System.out.println("We left shift "+val+" by 32: "+(val<<32));
 }

} </Code>

Sample Fix

First solution by making the hidden modulo operation visible

<code Java>

class ICAST_BAD_SHIFT_AMOUNT {

  public static void main(String[] args){
int val = -8;

System.out.println("We left shift "+val+" by 32: "+(val<<0)); // replaced by const%32
  }

}

</Code>

Second solution by changing the range of the value, taking into account that the programmer might have expected the shifted variable to have a bigger range.

<code Java>

class ICAST_BAD_SHIFT_AMOUNT {

 public static void main(String[] args){
long val = -8;//changed to long, if the programmer was expecting a bigger range

System.out.println("We left shift "+val+" by 32: "+(val<<32));
 }

}

</Code>

Evaluation Results

Benchmark project Precision Recall
FB JT Delta FB JT Delta
Project … …% …% …% …% …% …%
Project … …% …% …% …% …% …%

FB = FindBugs, JT = JTransformer, Delta = JTransformer - FindBugs

teaching/labs/mdse/2013/bug_descriptions/jt-bug-cor12.txt · Last modified: 2018/05/09 01:59 (external edit)

SEWiki, © 2023