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
,则带符号的值将被解释为负值
希望对您有所帮助...
很短,我在理解这段代码的工作原理时遇到问题,它比我的 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
希望对您有所帮助...