msg256
msg256

Reputation: 35

modifying hex in binary form

I would like to be able to convert from a hex byte to an 8 bit binary string or bit array, modify a single bit in the string and convert back into a hex byte.

In theory i would have the input of

 "FF"

convert it to binary and change one of the bits

 "11111111" => "11110111"

and convert it back

 "F7"

I cant get Convert.ToInt32() to work properly and Format("X2") wont work either. Any ideas?

private void changeDObit(int port, int bitNum, int state)
    {
        try
        {
            byte currentstate;
            instantDoCtrl1.Read(port, out currentstate);
            string data0Hex = currentstate.ToString("X2");
            string data0Binary = Convert.ToString(Convert.ToInt32(data0Hex, 16), 2).PadLeft(data0Hex.Length * 4, '0');

            if (!data0Binary[bitNum].Equals(state))
            {
                StringBuilder sb = new StringBuilder(data0Binary);
                sb[bitNum] = (char)state;
                data0Binary = sb.ToString();
                string strHex = string.Format("{0:X2}", sb);
                byte outdata = Convert.ToByte(strHex);
                instantDoCtrl1.Write(port, outdata);
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());

        }

    }

Upvotes: 0

Views: 281

Answers (1)

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391336

Here's a much simpler version of your entire method:

private void changeDObit(int port, int bitNum, int state)
{
    byte currentstate;
    instantDoCtrl1.Read(port, out currentstate);
    var bitValue = 1 << bitNum;
    currentstate = (currentstate & ~bitValue) | (state * bitValue);
    instantDoCtrl1.Write(port, outdata);
}

Assumptions:

  • bitNum = 0..7 where 0 is rightmost bit, 1 is next to the left, etc.
  • state is either 0 or 1

The way it works is as follows:

When you and two numbers together, bitwise, you effectively end up with all the bits that were 1 in both.

So, the first part of the expression:

(currentstate & ~bitValue)

ands together currentstate and ~bitValue.

So, what is ~bitValue? Well, in this case bitValue is 1 bit set, so it has a binary value of either 00000001, 00000010, 00000100, 00001000, 00010000, 00100000, 01000000 or 10000000.

~ inverts that, turning all 1's into 0's and vice versa. In effect, you're anding currentstate with 11111110, 11111101, 11111011, 11110111, 11101111, 11011111, 10111111 or 01111111, leaving all other bits as they were, but clearing out a single bit.

Then, the second part of the expression:

| (state * bitValue)

Here we multiply state, which is either 0 or 1, with bitValue, that same 7-zeroes-and-1-bit-set value from above, and the result is ored into the final result. In effect, if state is 1, we set the bit, otherwise we don't.

So, the expression is thus as follows:

  • First make sure the interesting bit is cleared
  • And then optionally (if state is 1), set it

Upvotes: 2

Related Questions