3

I found some code online that performs this task:

byte = byte >> field;
byte = byte & 0x01;
return(byte);

However, I don't understand why we can't just do this:

return(byte & field);

Will this work? Why or why not? Are there better implementations?

4

6 回答 6

3

第一个相当于:

return (byte >> field) & 0x01;

它真正做的是转移到有位置的位,如果该位被设置则field返回,否则。10

您建议的那个是不正确的,因为它不会转移到指定字段的偏移量。例如,byte & 5没有任何意义。

该函数也可以这样写:

return byte & (1 << field);

当然,如果您打算传递1 << 5给它而不是5,您可以按照自己的方式编写。

我想field是一个数字,表示我们感兴趣的位的位置,因此对于单个字节,它将在范围内0..7

于 2011-06-09T15:39:29.617 回答
1

在第一个代码示例中,field 是您想要其值的字段中位的位置。

在第二个示例中,字段必须是一个 int,该位设置为 1,即1 << field.

于 2011-06-09T15:38:35.997 回答
1

字节右移

field表示您从右侧 (LSB) 获得的字的位数。byte = byte >> field会将field字节的位数带到byteLSB 位置。然后byte = byte & 0x01与字节相加,0x01这意味着1如果它最初在位号中设置了位,则结果将在 LSB 中field包含 a,或者0如果在该位置清除了该位,则结果将包含 a。

例如,需要检查字节0x52是否设置了位号的测试4如下所示。

    byte   = 0x52 =  0 1 0 1 0 0 1 0

    field  = 0x04 =  0 0 0 0 0 1 0 0

    Operation: byte = byte >> field

    The bit number 4 is single quoted below. Note how it moves

                                  intermediate byte       | lost bits during
                                        states            | right shifting

    byte         = 0x52         = 0  1  0 '1' 0  0  1  0  |
    shift 1      = 0x29         = 0  0  1  0 '1' 0  0  1  | 0
    shift 2      = 0x14         = 0  0  0  1  0 '1' 0  0  | 1 0
    shift 3      = 0x0A         = 0  0  0  0  1  0 '1' 0  | 0 1 0
    shift 4      = 0x05         = 0  0  0  0  0  1  0 '1' | 0 0 1 0

    Note that the bit 4 is now moved at the LSB/righ most position of the byte
    now if we test the rightmost position of the above byte then we can check
    if the bit number 4 had its bit set or cleared, with the following operation

    Operation: byte = byte & 0x01

    byte is now 0x05

    byte         = 0x05  = 0 0 0 0 0 1 0 '1'
    AND                    & & & & & & &  &
                   0x01  = 0 0 0 0 0 0 0  1
                   ----    ----------------
                   0x01    0 0 0 0 0 0 0  1

   Now byte contains 0x01 so bit number 4 had the bit set. In the other case the
   final answer would be 0.

但是我们无法检查byte & field编号的位field是否设置或清除。这是因为field它只是一个二进制文件而不是掩码。如果我们这样做byte & field了,就会发生以下情况。

  byte         = 0x52  = 0 1 0 1 0 0 1 0
  AND                    & & & & & & & &
  field        = 0x04  = 0 0 0 0 0 1 0 0
                 ----    ---------------
                 0x00    0 0 0 0 0 0 0 0

具有field0x04,即其位号2集。通过这个操作,我们实际检查了是否设置了位数2。如果 的 值field50, 并且2将被设置,那么如果提取位的状态02的 值,则直接与上面类似的结果将导致byte,这可以采用四种可能的组合。

将 0x01 向左移动并制作掩码

测试 a 的位值的其他方法byte不是将其byte自身移动,而是将0x01掩码field时间向左移动,并将其与字节进行 AND 运算,并检查是否为零。(byte & (0x01 << field)) != 0设置编号位时为真,field否则为假。

   Operation: (0x01 << field)

      Shifting 0x01 to the left field times field = 0x04 for the example

                 = 0x01             = 0 0 0 0 0 0 0 1  
    shift 1      = 0x02             = 0 0 0 0 0 0 1 0
    shift 2      = 0x04             = 0 0 0 0 0 1 0 0
    shift 3      = 0x08             = 0 0 0 0 1 0 0 0
    shift 4      = 0x10             = 0 0 0 1 0 0 0 0


      After the left shift the '1' moves in the bit position 4
      Now we AND this with the byte to check if the bit position 4
      is set or clear.

  byte            = 0x52  = 0 1 0 1 0 0 1 0
  AND                       & & & & & & & &
  (0x01 << field) = 0x10  = 0 0 0 1 0 0 0 0
                    ----    ---------------
                    0x10    0 0 0 1 0 0 0 0

  Therefore the answer (0x01 != 0) is 1 there fore the bit 4 is set. It the bit 4
  was not set then the answer would be 0.

使用预先计算的掩码

如果您有一个需要定期测试的特定格式的字节,例如某个预定义字的某个位域,其中每个位表示某些特定事物,那么您可以保留预计算机掩码,它仅在特定位位置有一个将使用该面具进行测试。例如,要检查一个字节,预计算机掩码将是:

#define BIT_0 0x01 //(00000001)
#define BIT_1 0x02 //(00000010)
#define BIT_2 0x04 //(00000100)
#define BIT_3 0x08 //(00001000)
#define BIT_4 0x10 //(00010000)
#define BIT_5 0x20 //(00100000)
#define BIT_6 0x40 //(01000000)
#define BIT_7 0x80 //(10000000)

所以要测试第 4 位,byte我们必须做return (byte & BIT_4)return (byte & BIT_4) != 0;

根据位位置代表的宏名称可以设置。

于 2011-06-10T03:37:07.003 回答
1

如果您真的希望返回值为零或一,您可以

return ((byte & (1 << field)) != 0);

或者

return ((byte >> field) & 0x01);

如果您只关心返回值是零还是非零,那么这两种形式都会简化一点。

于 2011-06-09T15:46:48.237 回答
0

第一个示例将所需的位移动到返回的 LSB 中,但第二个示例只是屏蔽了所有不需要的位。

于 2011-06-09T15:50:27.473 回答
-1

这可以由结构给出。让我们说:

struct POWERTRAIN_ERROR 
{

    uint8 ERROR_CODE;

    unit8 LAMP_STATUS : 1;
    };

    struct POWERTRAIN_ERROR   pt_error;

    uint8 func ( struct POWERTRAIN_ERROR pt)

    {

    // do something with pt.ERROR_CODE (which is a byte) and pt.LAMP_STATUS which is a bit field

    // lets say, this function needs to return the status of 0th bit of ERROR_CODE 

    return ( pt.ERROR_CODE & 0x1) ;

}
于 2014-07-07T20:00:23.163 回答