Java中整数的位级表示
Java中整数的位级表示
Java在内存中以二进制形式存储数字。了解整数在位级别上的表示可以帮助我们进行某些操作。
在本教程中,我们将查看Java中数字表示的一些具体细节,并了解Java的位运算是如何工作的。
2. Java中的位运算
在Java中,整数使用32位表示,长整数使用64位。需要注意的是,Java使用2的补码表示负数。在这种情况下,如果第一位是1,则假定该数字为负数。负数是通过取数字,翻转所有的1和0,然后加1来计算的。
例如,在8位中,数字6是_0b00000110_。将其转换为-6,我们将其反转为_0b11111001_,然后加1,变成_0b11111010_。
此外,位运算为几个用例奠定了很好的基础,因为它们通常比完整的数学或逻辑表达式对CPU来说更快。
2.1. AND运算符 (&)
AND运算符(&)在两个32位整数之间执行位与操作:
int result = 0b1100 & 0b0111;
assertEquals(0b0100, result);
此操作独立评估每个位的位置。如果操作数中相应位都是1,则结果在该位置将有1;否则为0。在提供的示例中:
- 12的二进制表示(0b1100)
- 7的二进制表示(0b0111)
- 位与运算得到0b0100
- 结果为十进制值4
2.2. OR运算符 (|)
OR运算符(|)对两个数字的同一位执行位或操作:
int result = 0b1100 | 0b0111;
assertEquals(0b1111, result);
与AND运算符类似,OR运算符比较每个位位置。如果操作数中至少有一个相应位是1,则结果在该位置将有1。在这个例子中,结果为0b1111,等同于十进制值15。
2.3. XOR运算符 (^)
我们可以使用XOR运算符(^)进行位异或操作,其中对操作数中的相应位进行操作:
int result = 0b1100 ^ 0b0111;
assertEquals(0b1011, result);
此操作将结果位设置为1,如果操作数中的相应位不同。在提供的示例中,结果为0b1011,对应于十进制值11。
2.4. 位非运算符 (~)
位非运算符(~)反转其操作数的位,将1变成0,反之亦然:
int result = ~0b0101;
assertEquals(-0b0110, result);
每个位都被反转,将0变成1,反之亦然。此外,结果为_-0b0110_,使用二进制补码表示法,等同于十进制值_-6_。
2.5. 左移 (<<_) 和 右移 (_>>)
左移(`<<)运算符将一个数字的位向左移动指定数量的位置:
int result = 0b0101 << 2;
assertEquals(0b10100, result);
在这里,我们对变量_a_中存储的值执行位左移操作。此外,此操作将二进制表示向左移动两个位置,用零填充右侧空出的位置。
类似地,右移(>`>)运算符将位向右移动:
int result = 0b0101 >> 1;
assertEquals(0b10, result);
相反,我们通过将变量_a_的二进制表示向右移动一个位置来执行位右移操作。对于有符号整数,左侧空出的位置根据符号位填充。因此,正数保持为正,负数保持为负。
3. 使用位运算修改颜色的实际示例
在这个实际示例中,我们将探讨如何应用位运算来修改RGB值的颜色。
3.1. 原始颜色和掩码
int originalColor = 0xFF336699;
int alphaMask = 0xFF000000;
int redMask = 0x00FF0000;
int greenMask = 0x0000FF00;
int blueMask = 0x000000FF;
这里,我们将原始颜色初始化为_0xFF336699_,一个RGB颜色的十六进制表示。此外,定义了四个掩码(alphaMask, redMask, greenMask, 和 blueMask),以根据它们的位置提取单独的颜色组件。
int alpha = (originalColor & alphaMask) >>> 24;
int red = (originalColor & redMask) >>> 16;
int green = (originalColor & greenMask) >>> 8;
int blue = originalColor & blueMask;
我们使用位与操作和它们各自的掩码提取_alpha_, red, green, 和 blue 组件。然后,我们应用右移(>>>)将提取的位对齐到最低有效位(LSB)位置。
- alpha组件,通过(originalColor & alphaMask) >>> 24提取,结果是二进制的1111 1111
- red组件,通过(originalColor & redMask) >>> 16提取,是二进制的0011 0011
- green组件,通过(originalColor & greenMask) >>> 8提取,是二进制的0110 1001
- blue组件,通过_originalColor_ & _blueMask_提取,是二进制的1001 1001
3.3. 修改颜色组件
red = Math.min(255, red + 50);
green = Math.min(255, green + 30);
接下来,我们修改_red_和_green_组件,模拟颜色调整。此外,我们在进行修改时确保值不超过最大值255。
- 使用red = _Math.min(255, red + 50)_修改red组件,结果是二进制的0100 0010
- 使用green = _Math.min(255, green + 30)_修改green组件,结果是二进制的0111 1111
3.4. 重新创建修改后的颜色
int modifiedColor = (alpha << 24) | (red << 16) | (green << 8) | blue;
此外,我们使用位或(|)和左移(<<)操作结合修改后的alpha, red, green, 和 blue组件重新创建修改后的颜色。
重建的颜色计算为_modifiedColor = (alpha << 24) | (red << 16) | (green << 8) | blue_,结果是二进制的1111 1111 0010 0010 1101 0110 1001。
4. 结论
在本文中,我们查看了Java如何在内存中表示数字。我们查看了二进制表示以及如何使用它来理解位运算。
最后,我们查看了一个实际示例,展示了掩码和位移动在现实世界中的应用。
如常,本文的完整代码示例可以在GitHub上找到。