Search code examples
javabytebitsigncomplement

Understanding signed numbers and complements in java


I have a 3 byte signed number that I need to determine the value of in Java. I believe it is signed with one's complement but I'm not 100% sure (I haven't studied this stuff in more than 10 years and the documentation of my problem isn't super clear). I think the problem I'm having is Java does everything in two's complement. I have a specific example to show:

  • The original 3-byte number: 0xEE1B17

  • Parsed as an integer (Integer.parseInt(s, 16)) this becomes: 15604503

  • If I do a simple bit flip (~) of this I get (I think) a two's complement representation: -15604504

  • But the value I should be getting is: -1172713

What I think is happening is I'm getting the two's complement of the entire int and not just the 3 bytes of the int, but I don't know how to fix this.

What I have been able to do is convert the integer to a binary string (Integer.toBinaryString()) and then manually "flip" all of the 0s to 1s and vice-versa. When then parsing this integer (Integer.parseInt(s, 16)) I get 1172712 which is very close. In all of the other examples I need to always add 1 to the result to get the answer.

Can anyone diagnose what type of signed number encoding is being used here and if there is a solution other than manually flipping every character of a string? I feel like there must be a much more elegant way to do this.

EDIT: All of the responders have helped in different ways, but my general question was how to flip a 3-byte number and @louis-wasserman answered this and answered first so I'm marking him as the solution. Thanks to everyone for the help!


Solution

  • If you want to flip the low three bytes of a Java int, then you just do ^ 0x00FFFFFF.