Anon
Anon

Reputation: 5163

Bitwise operators in Java acting on two bytes

This should be simple but I'm having trouble changing some C code that uses bitwise operators and shifts into Java.

In C I have:

unsigned short Color(byte r, byte g, byte b)
{
  return( ((unsigned short)g & 0x1F )<<10 | ((unsigned short)b & 0x1F)<<5 | (unsigned short)r & 0x1F);
}

This function, Color, returns 16bits where 15 of them represent three 5bit values for red, green, and blue color channels. I'm trying to do something similar in Java except I'm having trouble with data types.

In java I have:

int r=someval, g=anotherval, b=yetanotherval;

And I want to convert these integers to a 2byte data type and use the same bitwise/shift operations as above.

What is the best way to approach this? I was thinking of a 2byte array but that seems unnecessary.

edit

So I gave it a try in Java with shorts but there still seems to be an issue. I started simple with:

short r=someval, g=anotherval, b=yetanotherval;
short colorData = g & 0x001F;

But the compiler complains: "cannot convert from int to short"

Upvotes: 2

Views: 4179

Answers (5)

J&#246;rn Horstmann
J&#246;rn Horstmann

Reputation: 34014

In your example

short r=someval, g=anotherval, b=yetanotherval;
short colorData = g & 0x001F;

Both g and the hex literal get automatically promoted to int because the logical and operator always works on and returns integers. You can of course cast the result back to short.

short colorData = (short)(g & 0x001F);

The same should work for the char datatype, which is in fact the only unsigned integer type on the JVM. I would recommend against using the char type in this way, unless this is an isolated performance/memory sensitive part of your program, since using char for arithmetic might seem strange and counterintuitive for other maintainers of the source.

Upvotes: 2

unwind
unwind

Reputation: 399813

You have the short type in Java as well, but it's always signed, there is no unsigned in Java.

Therefore, it might be better to use an int, so you don't need to use the sign bit to hold actual color data, which can be a bit (no pun intended!) confusing.

This should work as a starting point, at least:

int Color(int r, int g, int b)
{
  return ((g & 0x1F) << 10) | ((b & 0x1F) << 5) | (r & 0x1F);
}

I made the arguments int as well, for simplicity's sake.

Update: It sounds (and seems) as if you can actually use short, since you only need 15 bits for the color format. Then let's do that:

short Color(short r, short g, short b)
{
  return ((g & 0x1F) << 10) | ((b & 0x1F) << 5) | (r & 0x1F);
}

I haven't tried compiling the above, but it's likely that you'll get conversion errors and will need to add explicit short casts throughout to make it compile.

Upvotes: 2

codymanix
codymanix

Reputation: 29468

In java, all calculation operations, even with only types smaller than int, always result to an int, so you have to explicitly cast it back to short:

short colorData = (short)(g & 0x001F);

Upvotes: 2

Flavio
Flavio

Reputation: 11977

Since you are using only 15 bits, the sign bit on the short data type will be no problem.

Upvotes: 1

Jules
Jules

Reputation: 1371

char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive).

http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

The Java char datatype is 2 bytes by default.

Upvotes: 1

Related Questions