The goal is to add two
byte values while avoiding overflow. To this end, we cast them to integers, and we use bit-masking to avoid sign extension when casting. The unsuccessful version is highlighted in red, while the successful version is green:public class ConvertBytes {
public static void main(String[] args) {
byte a = 127;
byte b = 126;
int bad = ((int)a) & 0xff + ((int)b) & 0xff;
System.out.println(bad);
int good = ((int)a & 0xff) + ((int)b & 0xff);
System.out.println(good);
}
}
When this program is executed,
bad is 125 and good is 253. I can't believe that after 13 years as an active Java programmer (with 11 years before that as an active C++ programmer) I made so elementary a mistake, but I'm posting it here in hopes it will be a useful warning to others. For whatever reason, I assumed that bitwise-and had a higher precedence than addition, perhaps because it is a traditionally "multiplicative" operator. As it turns out, its precedence is actually much lower.
A further observation is that this is not what I thought the bug was originally. At first, I thought I had somehow messed up the casting. It was only after I rechecked it carefully that I realized I was killing the higher-order bits with the bitwise and.
No comments:
Post a Comment