STM32上指定位置数组沿有效位计算
Effective bits calculation along the array in specified position on STM32
我想知道是否有人知道计算数组指定位置位的有效方法?
您可以只循环数组值并使用按位和运算符测试位,如下所示:
int arr[] = {1,2,3,4,5};
// 1 - 001
// 2 - 010
// 3 - 011
// 4 - 100
// 5 - 101
int i, bitcount = 0;
for (i = 0; i < 5; ++i){
if (arr[i] & (1 << 2)){ //testing and counting the 3rd bit
bitcount++;
}
}
printf("%d", bitcount); //2
请注意,我选择了 1 << 2
,它测试从右边数第三位或第三个最低有效位,只是为了更容易显示。现在 bitCount
现在将保存 2
,这是设置为 1
的 3rd
位数。
Take a look at the result in Ideone
在您的情况下,您需要检查第 5 位,它可以表示为:
1 << 4
0x10000
16
第8位:
1 << 7
0x10000000
256
因此根据您的位进行调整会给您:
int i, bitcount8 = 0, bitcount5 = 0;
for (i = 0; i < your_array_size_here; ++i){
if (arr[i] & 0x10000000){
bitcount8++;
}
if (arr[i] & 0x10000){
bitcount5++;
}
}
如果您需要计算其中的许多,那么这个解决方案不是很好,您最好创建一个位计数数组,然后使用另一个 for
循环计算它们:
int i, j, bitcounts[8] = {0};
for (i = 0; i < your_array_size_here; ++i){
for (j = 0; j < 8; ++j){
//j will be catching each bit with the increasing shift lefts
if (arr[i] & (1 << j)){
bitcounts[j]++;
}
}
}
在这种情况下,您将通过索引访问位计数:
printf("%d", bitcounts[2]); //2
假设OP想要计算活跃位
size_t countbits(uint8_t *array, int pos, size_t size)
{
uint8_t mask = 1 << pos;
uint32_t result = 0;
while(size--)
{
result += *array++ & mask;
}
return result >> pos;
}
令位位置差(例如本例中的 7 - 4)为 diff
。
如果 2diff > n,则代码可以同时添加两个位。
void count(const uint8_t *Array, size_t n, int *bit7sum, int *bit4sum) {
unsigned sum = 0;
unsigned mask = 0x90;
while (n > 0) {
n--;
sum += Array[n] & mask;
}
*bit7sum = sum >> 7;
*bit4sum = (sum >> 4) & 0x07;
}
如果处理器具有快速乘法并且 n
仍然不会太大,例如本例中的 n < pow(2,14)
。 (或者一般情况下 n < pow(2,8)
)
void count2(const uint8_t *Array, size_t n, int *bit7sum, int *bit4sum) {
// assume 32 bit or wider unsigned
unsigned sum = 0;
unsigned mask1 = 0x90;
unsigned m = 1 + (1u << 11); // to move bit 7 to the bit 18 place
unsigned mask2 = (1u << 18) | (1u << 4);
while (n > 0) {
n--;
sum += ((Array[n] & mask1)*m) & mask2;
}
*bit7sum = sum >> 18;
*bit4sum = ((1u << 18) - 1) & sum) >> 4);
}
算法:代码使用掩码、乘法、掩码来分隔 2 位。低位保持在低位,而高位移到高位。然后发生并行添加。
循环避免了循环本身之外的任何分支。这可以实现快速代码。 YMMV.
对于更大的 n
,将其分解为对 count2()
的多次调用
我想知道是否有人知道计算数组指定位置位的有效方法?
您可以只循环数组值并使用按位和运算符测试位,如下所示:
int arr[] = {1,2,3,4,5};
// 1 - 001
// 2 - 010
// 3 - 011
// 4 - 100
// 5 - 101
int i, bitcount = 0;
for (i = 0; i < 5; ++i){
if (arr[i] & (1 << 2)){ //testing and counting the 3rd bit
bitcount++;
}
}
printf("%d", bitcount); //2
请注意,我选择了 1 << 2
,它测试从右边数第三位或第三个最低有效位,只是为了更容易显示。现在 bitCount
现在将保存 2
,这是设置为 1
的 3rd
位数。
Take a look at the result in Ideone
在您的情况下,您需要检查第 5 位,它可以表示为:
1 << 4
0x10000
16
第8位:
1 << 7
0x10000000
256
因此根据您的位进行调整会给您:
int i, bitcount8 = 0, bitcount5 = 0;
for (i = 0; i < your_array_size_here; ++i){
if (arr[i] & 0x10000000){
bitcount8++;
}
if (arr[i] & 0x10000){
bitcount5++;
}
}
如果您需要计算其中的许多,那么这个解决方案不是很好,您最好创建一个位计数数组,然后使用另一个 for
循环计算它们:
int i, j, bitcounts[8] = {0};
for (i = 0; i < your_array_size_here; ++i){
for (j = 0; j < 8; ++j){
//j will be catching each bit with the increasing shift lefts
if (arr[i] & (1 << j)){
bitcounts[j]++;
}
}
}
在这种情况下,您将通过索引访问位计数:
printf("%d", bitcounts[2]); //2
假设OP想要计算活跃位
size_t countbits(uint8_t *array, int pos, size_t size)
{
uint8_t mask = 1 << pos;
uint32_t result = 0;
while(size--)
{
result += *array++ & mask;
}
return result >> pos;
}
令位位置差(例如本例中的 7 - 4)为 diff
。
如果 2diff > n,则代码可以同时添加两个位。
void count(const uint8_t *Array, size_t n, int *bit7sum, int *bit4sum) {
unsigned sum = 0;
unsigned mask = 0x90;
while (n > 0) {
n--;
sum += Array[n] & mask;
}
*bit7sum = sum >> 7;
*bit4sum = (sum >> 4) & 0x07;
}
如果处理器具有快速乘法并且 n
仍然不会太大,例如本例中的 n < pow(2,14)
。 (或者一般情况下 n < pow(2,8)
)
void count2(const uint8_t *Array, size_t n, int *bit7sum, int *bit4sum) {
// assume 32 bit or wider unsigned
unsigned sum = 0;
unsigned mask1 = 0x90;
unsigned m = 1 + (1u << 11); // to move bit 7 to the bit 18 place
unsigned mask2 = (1u << 18) | (1u << 4);
while (n > 0) {
n--;
sum += ((Array[n] & mask1)*m) & mask2;
}
*bit7sum = sum >> 18;
*bit4sum = ((1u << 18) - 1) & sum) >> 4);
}
算法:代码使用掩码、乘法、掩码来分隔 2 位。低位保持在低位,而高位移到高位。然后发生并行添加。
循环避免了循环本身之外的任何分支。这可以实现快速代码。 YMMV.
对于更大的 n
,将其分解为对 count2()