2014-01-29 36 views
3

背景:我有像这样的二进制表示一个32位的整数:改变一个32位的整数的特定位中的Java

1111 1111 0000 0000 0000 0000 1111 1111 

注:这是在ARGB的二进制表示值为Color.BLUE。我正在使用它来说明目的,但它与我试图解决的情况有关。

问题:我试图让其二进制表示看起来像这样改变的高位:

1000 0000 0000 0000 0000 0000 1111 1111 

或者更简单地说,前八点的高位应该改变像这样:

1111 1111 -> 1000 0000 

目前的解决方案尝试:到目前为止,我已经成功地通过屏蔽掉前八点的高位,而日恩“并称”使用逐所需的值“或”,像这样:

int colourBlue = Color.BLUE.getRGB(); // equal to binary value at top of question 
int desiredAlpha = (0x80 << 24); // equal to 1000 0000 0000 0000 0000 0000 0000 0000 

// Mask out the eight high order bits, and add in the desired alpha value 
int alteredAlphaValue = (colourBlue & 0x00FFFFFF) | desiredAlpha; 

虽然这样做目前的工作,无可否认它已经因为我的计算机体系结构类一段时间,我没有很多的经验但仍然使用按位运算符和较低级别的位操作。

我的问题:我的解决方案是完成此任务的正确方法吗?如果它在某种程度上不合适(或者只是简单的“哑”),那么实现改变特定位的目标是更好的(或正确的)方法?

+1

你知道你的解决方案也会消灭红色和绿色的部分,如果有的话,对吧? –

+0

如果您的位按每个8位排列为ARGB,则您的方法是正确的。 –

+2

@ user2864740,如果它们的起始位置是0x00,则您的方法不会将高位更改为0x80。 –

回答

2

从C#代码转换为Java的(未经测试):

public static int setBits(int orig, int newBits, int startBit, int length) 
{ 
    int mask = Mask(startBit, length); 
    return (orig & ~mask) | (bits << startBit & mask); 
} 

public int Mask(int startBit, int length) 
{ 
    if (length ==32) 
     return Integer.MAX_VALUE; 
    else 
     return (1 << (1 << length) - 1) << startbit; 
} 

或者,如果你愿意,你可以直接指定面具,避免了位移:

public static int setBits(int orig, int newBits, int mask) 
{ 
    return (orig & ~mask) | (bits & mask); 

} 

当然,如果您将RGB值作为32位数字传递,则始终可以使用convert it to a byte array,反之亦然,这使得操作变得更加容易。

+0

如果要做很多事情,您可以通过前面创建掩码的二维阵列来提高性能 –

+0

实际上,它不太可能您将通过Java以这种方式提高性能。 1)预先计算可能的掩码数量可能是棘手的。 2)Java中的数组提取成本包括边界检查 - 额外获取长度为+2的比较结果。 3)对于2-D数组,读取开销(至少)加倍。 4)大数组提取(随机索引)会给你一个缓存未命中等。相比之下,按位操作是寄存器注册。 –