简体   繁体   English

在STM32上指定位置沿数组的有效位计算

[英]Effective bits calculation along the array in specified position on STM32

I'm wondering if someone know effective approach to calculate bits in specified position along array? 我想知道是否有人知道有效的方法来计算沿数组的指定位置中的位?

在此处输入图片说明

You can just loop the array values and test for the bits with a bitwise and operator, like so: 您可以循环数组值并使用按位和运算符测试位,如下所示:

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

Note that i opted for 1 << 2 which tests for the 3rd bit from the right or the third least significant bit just to be easier to show. 请注意,我选择1 << 2来测试右边的第三位或最低的第三位,以便于显示。 Now bitCount would now hold 2 which are the number of 3rd bits set to 1 . 现在, bitCount现在将保存2 ,这是设置为13rd位的数目。

Take a look at the result in Ideone 看看Ideone的结果

In your case you would need to check for the 5th bit which can be represented as: 在您的情况下,您需要检查第5位,该位可以表示为:

  • 1 << 4
  • 0x10000
  • 16

And the 8th bit: 和第8位:

  • 1 << 7
  • 0x10000000
  • 256

So adjusting this to your bits would give you: 因此,将其调整为适合您的位数将为您提供:

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++;
    }
}

If you need to count many of them, then this solution isn't great and you'd be better off creating an array of bit counts, and calculating them with another for loop: 如果您需要计数很多,那么该解决方案就不好了,最好创建一个数组,然后用另一个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]++;
        }
    }
}

And in this case you would access the bit counts by their index: 在这种情况下,您将按其索引访问位数:

printf("%d", bitcounts[2]); //2

Check this solution in Ideone as well 还要在Ideone中检查此解决方案

Assuming that OP wants to count active bits 假设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;
}

Let the bit position difference (eg 7 - 4 in this case) be diff . 让位位置差(在这种情况下为diff )为diff

If 2 diff > n, then code can add both bits at the same time. 如果2 diff > 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;
}

If the processor has a fast multiply and n is still not too large, like n < pow(2,14) in this case. 如果处理器具有快速乘法并且n仍然不太大,例如n < pow(2,14)在这种情况下。 (Or n < pow(2,8) in the general case) (或者一般情况下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);
}

Algorithm: code is using a mask, multiply, mask to separate the 2 bits. 算法:代码使用掩码,乘法,掩码将2位分开。 The lower bit remains in it low position while the upper bit is shifted to the upper bits. 当高位移位到高位时,低位保持在低位。 Then a parallel add occurs. 然后发生并行添加。

The loop avoids any branching aside from the loop itself. 循环避免了循环本身之外的任何分支。 This can make for fast code. 这可以使代码更快速。 YMMV . YMMV

With even larger n , break it down into multiple calls to count2() 如果n更大,则将其分解为对count2()多次调用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM