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