0

I am working on a file reader and came into a problem when trying to read a short. In short (punintended), java is converting a two bytes I'm using to make the short into an int to do bitwise operations and is converting it in a way to keep the same value. I need to convert the byte into an int in a way that would preserve its value so the bits stayed the same.

example of what's happening:

byte number = -1; //-1
int otherNumber = 1;
number | otherNumber; // -1

example of what I want:

byte number = -1; //-1
int otherNumber = 1;
number | otherNumber; // 129
  • 1
    Welcome to Stack Overflow. I can't understand the question. You say that this is about converting a short to an int, but the code shows packing two bytes into a short. Please read [ask] and [mre] and make it possible to understand the problem, by showing a) code that someone else can copy and paste, without changing anything, in order to see a problem directly; b) exactly what you think should happen when running that code (and why); c) exactly what does happen instead (copy and paste the terminal output) – Karl Knechtel Sep 17 '22 at 04:24
  • I edited my post. Sry. Is this more understandable? – BREgitLEEhub2222 Sep 17 '22 at 04:48
  • Oh. In that case, please see https://stackoverflow.com/questions/4266756/can-we-make-unsigned-byte-in-java. – Karl Knechtel Sep 17 '22 at 12:10

1 Answers1

3

This can be done pretty easily with some bit magic.

I'm sure you're aware that a short is 16 bits (2 bytes) and an int is 32 bits (4 bytes). So, between an integer and a short, there is a two-byte difference. Now, for positive numbers, copying the value of a short to an int is effectively copying the binary data, however, as you've pointed out, this is not the case for negative numbers.

Now let's look at how negative numbers are represented in binary. It's a bit confusing, so I'll try to keep it simple. Modern systems use what's called the two's compliment to store negative numbers. Basically all this means is that the very first bit in the set of bytes representing the number determines whether or not it's negative. For mathematical purposes, the rest of the bits are also inverted and offset 1 bit to the right (since you can't have negative 0). For example, 2 as a short would be represented as 0000 0000 0000 0010, while -2 would be represented as 1111 1111 1111 1110. Now, since the bytes are inverted in a negative number, this means that -2 in int form is the same but with 2 more bytes (16 bits) at the beginning that are all set to 1.

So, in order to combat this, all we need to do is change the extra 1s to 0s. This can be done by simply using the bitwise and operator. This operator goes through each bit and checks if the bits at each position in each operand are a 1 or a 0. If they're both 1, the bit is flipped to a 0. If not, nothing happens.

Now, with this knowledge, all we need to do is create another integer where the first two bytes are all 1. This is fairly simple to do using hexidecimal literals. Since they are an integer by default, we simply need to use this to get four bytes of 1s. With a single byte, if you were to set every bit to 1, the max value you can get is 255. 255 in hex is 0xFF, so 2 bytes would be 0xFFFF. Pretty simple, now you just need to apply it.

Here is an example that does exactly that:

short a = -2;
int b = a & 0xFFFF;

You could also use Short.toUnsignedInt(), but where's the fun in that?

Jesse
  • 1,386
  • 3
  • 9
  • 23