0

I am using IAR embedded workbench and C. I would like to create a mask and decide whether next bit for transmit is 1 or 0.

I tried this but didn't work

int transmit(int signal, int number_of_bits)
{

    int mask;
    for (int i = 0; i < number_of_bits; i++)
    {
        mask = pow(2,number_of_bits-1-i)
        if ((signal & mask) == 0) // bit '0'
        {
            transmit0();
        }
        else // bit '1'
        {
            transmit1();
        }
    }
}

And I tried this, it tranmits 0001 but i'm trying to transmit 1000 (vice versa)

int transmit(int signal, int number_of_bits)
{

    int mask;
    for (int i = 0; i < number_of_bits; i++)
    {
        mask = (1 << i);
        if ((signal & mask) == 0) // bit '0'
        {
            transmit0();
        }
        else // bit '1'
        {
            transmit1();
        }
    }
}
Mustafa
  • 37
  • 1
  • 7
  • 5
    `^` is the bitwise XOR operator in C, instead of the exponentiation operator. – L. F. May 12 '19 at 10:20
  • 2
    And `<<` is the bit-shift operator. `1 << i` happens to equal the `i`th power of 2 in your case. – L. F. May 12 '19 at 10:21
  • You are right but lets say i'm sending 8 which equals to 1000. In for loop, firstly 'i' equals to 0 and 2^0=1 how result 8&1 can be equal to 1 ? – Mustafa May 12 '19 at 10:35
  • 8&1 is 0, it cannot be 1. Your second way using `mask = (1 << i);` is the right way – bruno May 12 '19 at 10:39
  • The mask could have also been initialized to `1` at the start of the program. And then you'd only have to do `mask <<= 1` every iteration to get the next power of 2 in your mask (iow: go to the next bit). – E. van Putten May 12 '19 at 10:44
  • It also seems like the 'working' example goes from bit 0 ... N while the first non-working snippet was going from bit N ... 0. – E. van Putten May 12 '19 at 10:45
  • Yes that's the point because i'm trying to send N'th bit first. – Mustafa May 12 '19 at 10:52
  • [Why is my power operator (^) not working?](https://stackoverflow.com/q/4843304/995714) – phuclv May 12 '19 at 10:58

2 Answers2

0

As noticed by @L.F., ^ is NOT a power operator, alas <<, the bitwise shift operator, does the trick.

Marcus Vinicius Pompeu
  • 1,219
  • 1
  • 11
  • 24
  • Thank you. But, lets say i'm sending 8 which equals to 1000. In for loop, firstly 'i' equals to 0 and 2^0=1 how result 8&1 can be equal to 1 ? – Mustafa May 12 '19 at 10:34
  • The code is supposed to check one bit (that's what the mask is for, to filter out one bit) and then checks if it is 0. If it is not zero (and whatever the exact value is - can only be a power of 2) -- that must mean the bit you are testing is '1' regardless of its place. – E. van Putten May 12 '19 at 10:37
  • 2
    @MustafaUysal `2^0` is 2, not 1. `^` does a **xor**, `2^0` is **not** 2 power 0 – bruno May 12 '19 at 10:43
  • @MustafaUysal, @bruno is right. `2^0 == 2` because `^` is a `XOR` bitwise operator, not a `POW` operator as you seem to expecting. `2 POW 0 == 1`, but `2 XOR 0 == 2` – Marcus Vinicius Pompeu May 12 '19 at 10:47
  • thx. my problem is: mask rotates toward left but i'm sending most significant bit first. how it's masking with 1 of 1000 first and later rotates left and masking with 0s? – Mustafa May 12 '19 at 10:48
  • `<<` counterintuitively yelds a BIGGER result. '(B(001b) << 1) == B(010)' / '1 << 1 == 2', or '(B(010) << 1) == B(100)' / '2 << 1 == 4' – Marcus Vinicius Pompeu May 12 '19 at 10:57
  • Ah, I adjusted my answer a bit. The idea is to initialize mask with only the highest bit set (so mask = 1 << (numbits-1)). Which would give you the biggest bit number. Then shift right every time inside the loop (mask >>= 1). – E. van Putten May 12 '19 at 11:15
0

Here mask is the variable that will always contain a "power of 2" value. The goal is to only have one bit set in the mask at all times. This mask is used to test each bit in "isolation".

In combination with the logical AND-function, you can see it as a filter that gives you only the value that particular bit corresponds to or nothing (zero).

Remember that the value of a binary word with only one bit set always corresponds to a power 2 value by definition. So after the test of a single bit you will see either zero or a power of 2 value.

Let's look at some practical values while the program is running (assuming 8 bits). So in the for loop, this is what the value of mask looks like over time:

00000001
00000010
00000100
00001000
00010000
...

Note: you can also go into the reverse direction, for instance if the receiver wants to see the highest bit first and the lowest last. Don't know what is needed here, but just so you know. If you want to go in reverse, you initialize mask with (1 << (num_bits-1)) then go one step to the right every time in the loop itself mask >>= 1).

Every mask value is bitwise AND-ed (& operator) with the input value signal to "filter" out that one particular bit we're interested in.

Remember: the outcome of this AND operation is still multiple bits -- not a single bit, so we can't look for a value of 1 (we'd also have to test for the cases 2, 4, 8 ... etc.).

Example, so let's say all the bits are on, then the logical AND output will look like this:

00000001 AND 11111111 = 00000001
00000010 AND 11111111 = 00000010
00000100 AND 11111111 = 00000100
00001000 AND 11111111 = 00001000
00010000 AND 11111111 = 00010000
...

Note how the outcome follows the mask in this case. Although the values differ every time, you know that when you got something nonzero, the bit you are testing must be high!

And if all the bits are off you will see this:

00000001 AND 00000000 = 00000000
00000010 AND 00000000 = 00000000
00000100 AND 00000000 = 00000000
00001000 AND 00000000 = 00000000
00010000 AND 00000000 = 00000000

You will note it's easier to check if the result is zero. That means the bit was off. It's also why the code only checks for a value of zero, it knows the bit is 1 in all the other cases!

Now the trick is to get the correct mask value. What you want is shift a bit value of 1 left to the correct place. So if you start testing for bit 4 for instance, you'd shift 1 four places to the left and you will get (00010000 binary).

For this we use the bit shift left operator <<.

As others have already said, ^ unfortunately does something completely different (XOR), which adds to the whole confusion.

E. van Putten
  • 615
  • 7
  • 17