屏蔽按位运算符

时间:2014-01-28 09:25:27

标签: c bit-manipulation

gcc (GCC) 4.8.2
c89

您好,

屏蔽按位运算符:

我想屏蔽以下内容:

SIGNAL_ID_EVENT_DTMF_1 | SIGNAL_ID_EVENT_DTMF_STAR | SIGNAL_ID_EVENT_DTMF_POUND

我使用以下功能设置上述内容:

static void g_convert2_ipm_digits(unsigned short *terminator)
{
    *terminator = SIGNAL_ID_EVENT_DTMF_1 | SIGNAL_ID_EVENT_DTMF_STAR | SIGNAL_ID_EVENT_DTMF_POUND;

}

所以当一个数字进入I& (和)看模式是否存在:

static apk_bool_t g_check_term_digit(unsigned short terminators, unsigned short digit)
{
    if(terminators & digit) {
        return TRUE;
    }
    return FALSE
}

但是,无论数字是多少,该函数始终返回true。只应该为我掩盖的那些返回true。

当我在上面的函数中检查调试器时,我得到以下函数。但是,这不应该返回true,因为已按下的数字是5。

(gdb) p terminators
$22 = 11
(gdb) p digit
$23 = 5

我期望的数字在下面的枚举中定义:

typedef enum
{       
        SIGNAL_ID_EVENT_DTMF_0                                               = 0x0,
        SIGNAL_ID_EVENT_DTMF_1                                               = 0x1,
        SIGNAL_ID_EVENT_DTMF_2                                               = 0x2,
        SIGNAL_ID_EVENT_DTMF_3                                               = 0x3,
        SIGNAL_ID_EVENT_DTMF_4                                               = 0x4,
        SIGNAL_ID_EVENT_DTMF_5                                               = 0x5,
        SIGNAL_ID_EVENT_DTMF_6                                               = 0x6,
        SIGNAL_ID_EVENT_DTMF_7                                               = 0x7,
        SIGNAL_ID_EVENT_DTMF_8                                               = 0x8,
        SIGNAL_ID_EVENT_DTMF_9                                               = 0x9,
        SIGNAL_ID_EVENT_DTMF_STAR                                            = 0xa,
        SIGNAL_ID_EVENT_DTMF_POUND                                           = 0xb,
        SIGNAL_ID_EVENT_DTMF_A                                               = 0xc,
        SIGNAL_ID_EVENT_DTMF_B                                               = 0xd,
        SIGNAL_ID_EVENT_DTMF_C                                               = 0xe,
        SIGNAL_ID_EVENT_DTMF_D                                               = 0xf,
}

非常感谢任何建议,

2 个答案:

答案 0 :(得分:5)

您需要使用两个值的幂:例如

SIGNAL_ID_EVENT_DTMF_0   = 0x01,
SIGNAL_ID_EVENT_DTMF_1   = 0x02,
SIGNAL_ID_EVENT_DTMF_2   = 0x04,
SIGNAL_ID_EVENT_DTMF_3   = 0x08,
SIGNAL_ID_EVENT_DTMF_4   = 0x10,

因为当您应用逻辑OR运算时,您正在合并数字的位图:

R = SIGNAL_ID_EVENT_DTMF_1 | SIGNAL_ID_EVENT_DTMF_3 | SIGNAL_ID_EVENT_DTMF_4

等于(二进制):

R = 00010 | 01000 | 10000 => 11010

所以稍后你可以使用&查看特定值是否为真的操作:

R & SIGNAL_ID_EVENT_DTMF_3 => true

,因为

11010 & 01000 => 01000 != 0 => true

答案 1 :(得分:2)

例如, SIGNAL_ID_EVENT_DTMF_3设置了两个位。比特为零和一。你正在做的不是在你期望的意义上制作位掩码。看来你也应该使用位移:

*terminator = (1 << SIGNAL_ID_EVENT_DTMF_1) |
              (1 << SIGNAL_ID_EVENT_DTMF_STAR) |
              (1 << SIGNAL_ID_EVENT_DTMF_POUND);

然后在屏蔽时使用digit执行相同的操作:

if (terminators & (1 << digit)) { ... }