Paul Richter
Paul Richter

Reputation: 11072

Altering specific bits of a 32-bit integer in Java

Background: I have a 32-bit integer with a binary representation like so:

1111 1111 0000 0000 0000 0000 1111 1111

Note: This is the binary representation of the ARGB value of Color.BLUE. I'm using this for illustration purposes, but it is relevant to a situation I am attempting to solve.

The Problem: I am attempting to alter the high order bits so that its binary representation looks like this:

1000 0000 0000 0000 0000 0000 1111 1111

Or more simply, the first eight high order bits should be changed like so:

1111 1111 -> 1000 0000

Current Solution Attempt: Thus far, I've been successful by masking out the first eight high order bits, and then "adding" the desired value using bitwise "or", like so:

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;

While this does presently work, admittedly it has been some time since my computer architecture classes, and I have not had a lot of experience yet working with bitwise operators and lower level bit manipulation.

My question: Is my solution the correct way to accomplish this task? If it is in some way improper (or just plain "dumb"), what is a better (or correct) way to achieve the goal of altering specific bits?

Upvotes: 3

Views: 1870

Answers (1)

Robert Harvey
Robert Harvey

Reputation: 180808

Transcoded from C# to Java (untested):

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;
}

Or, if you prefer, you can just specify the mask directly, and avoid the bit-shifting:

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

}

Of course, if you're being handed the RGB value as a 32 bit number, you could always convert it to a byte array and vice versa, which makes the manipulations much easier.

Upvotes: 2

Related Questions