I have a problem while doing the AND operator using 0xff.
public Pixel(int x, int y, int p) {
this.x = x;
this.y = y;
pixelValue = p;
A = (byte) ((p>>24) & 0xff);
R = (byte) ((p>>16) & 0xff);
R = (byte) (R&0xff);
G = (byte) ((p>>8) & 0xff);
B =(byte) (p & 0xff);
printAll();
}
void printAll() {
System.out.println("A "+Integer.toBinaryString(A));
System.out.println(Byte.toUnsignedInt(A));
System.out.println("R "+Integer.toBinaryString(R));
System.out.println(Byte.toUnsignedInt(R));
System.out.println("G "+Integer.toBinaryString(G));
System.out.println(Byte.toUnsignedInt(G));
System.out.println("B "+Integer.toBinaryString(B));
System.out.println(Byte.toUnsignedInt(B));
System.out.println("pixelValue"+pixelValue);
System.out.println(Integer.toBinaryString((byte)(pixelValue)));
}
When doing Pixel p = new Pixel(0,0,2145687240);
I get
A 1111111
127
R 11111111111111111111111111100100
228
G 11111111111111111111111110010110
150
B 11111111111111111111111111001000
200
pixelValue-56
11111111111111111111111111001000
Question being, why are R, G and B filled with 1s? and why is A only 7 bits? why when calling &0xff I get 1111111111111111111111111100100? shouldn't this cancel everything but the first 8 bytes?
Bytes go from 0
to 255
inclusive since they can hold 2^8=256
values. That's the unsigned definition, at least.
The question to ask yourself here is: how do negative numbers get represented? The typical method is using something known as the two's complement. The first bit, instead of representing 0
when off and 2^(n-1)
when on, like it usually would, instead represents 0
when off and -2^(n-1)
when on.
Thus, 228
is stored internally as 11100100
. If you convert this from base 2 you will see that this equals 228
... but only when unsigned.
When signed, the last 7 bits represent 100
. Then, the first bit, instead of representing 128
, instead represents -128
. Thus, the value is -28
when signed.
Then, when converting this to an integer, since an integer has 32 bits, then the first bit will represent -2147483648
, and thus the last 31 bits will need to represent 28 + 2147483648
, which is where 1111111111111111111111111100100
comes from. Thus, the 32 bit representation of -28
is 11111111111111111111111111100100
.
If you want to actually have 228
, you'd probably want to call Integer.toBinaryString
on the result of Byte.toUnsignedInt
, which, as the name suggests, converts it as an unsigned number. The issue here is that it's being signed, which means that it's -28
, not 228
like you want.