C 按位运算左移和按位或

C Bitwise operations left shift and bitwise OR

很短,我在理解这段代码的工作原理时遇到问题,它比我的 20 多行代码更有效地获得相同的结果。我了解左移和按位 Or 应该如何工作,但希望获得一些指导以了解两者如何结合在一起以使 for 循环中的行工作。 代码旨在接收给定大小(计数)的位(位)数组和return位的整数值。

unsigned binary_array_to_numbers(const unsigned *bits, size_t count) {
    unsigned res = 0;
    for (size_t i = 0; i < count; i++)
        res = res << 1 | bits[i]; 
    return res;
}

编辑:根据要求,我的新手解决方案仍然通过了所有测试:添加了可能分配给位的示例[]

unsigned binary_array_to_numbers(const unsigned *bits, size_t count)
{
        int i, j = 0;
        unsigned add = 0;
        for (i = count - 1; i >= 0; i--){
                if(bits[i] == 1){
                        if(j >= 1){
                                j = j * 2;
                                add = add + j;
                        }
                        else{
                                j++;
                                add = add + j;

                        }
                }
                else {
                        if( j>= 1){
                                j = j * 2;
                        }
                        else{
                                j++;
                        }
                }
        }

        return add;
}

void main(){
        const unsigned bits[] = {0,1,1,0};
        size_t count = sizeof(bits)/sizeof(bits[0]);
        binary_array_to_numbers(bits, count);
}

将它们视为 2 个操作,我将 res= ... 重写为 2 行

res = res << 1
res = res | 1

第一遍 res 设置为 1,下一次移动 *2 然后因为它现在是偶数 +1

细分:

  • 二进制数的每个左移操作有效地相乘 它由 2 0111(7) << 1 = 1110(14)
  • 考虑rhubarbdog answer - 该操作可以看作是两个独立的操作。首先左移(乘以 2),然后与正在审查的当前位进行 OR
  • PC不区分显示值和二进制 数字的表示

让我们尝试回顾一下您输入的案例:

bits = {0, 1, 0, 1};
count = 4;
unsigned binary_array_to_numbers(const unsigned *bits, size_t count) {
    unsigned res = 0;
    for (size_t i = 0; i < count; i++)
        res = res << 1 // (a)
        res = res | bits[i]; /* (b) according to rhubarbdog answer */
    return res;
}

迭代 0:
- 位[i] = 0;
- (a) res = b0; (0的左移)
- (b) res = b0; (与 0 按位或)

迭代 1:
- 位 [i] = 1;
- (a) res = b0; (0的左移)
- (b) res = b1; (与 1 按位或)

迭代 2:
- 位[i] = 0;
- (a) res = b10; (左移1 - 十进制值为2)
- (b) res = b10; (与 0 按位或)

迭代 3:
- 位 [i] = 1;
- (a) res = b100; (左移1 - 十进制值为4)
- (b) res = b101; (与 1 按位或)

res 的最终结果如预期的那样是二进制 (101) 和十进制 (5) 注意:必须使用 unsigned,因为如果 MSB 为 1

,则带符号的值将被解释为负值

希望对您有所帮助...