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 b开发者_运维百科ut 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"
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.
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);
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.
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.
Since you are using only 15 bits, the sign bit on the short
data type will be no problem.
精彩评论