在C语言中提取特定范围的位并找出它们之间的零数

在C语言中提取特定范围的位并找出它们之间的零数,c,C,我想在整数变量中提取特定范围的位 例如:0xA5 10100101 我想从第2位提取到第5位。i、 e 1001到一个变量,并计算它们之间的零数 我有另一个变量,它给出了起点,这意味着在这种情况下,变量的值是2。因此,可以通过0xA5>>2找到起点。 第5位位置在这里是一个随机位置。表示它可以是6或7。其主要思想是在第二位之后将哪个位设置为1。我得把它提取出来 剩下的部分我怎么做 int result = (0xA5 >> 2) & 0x0F; &运算符的真值表 &运算符的

我想在整数变量中提取特定范围的位

例如:0xA5 10100101

我想从第2位提取到第5位。i、 e 1001到一个变量,并计算它们之间的零数

我有另一个变量,它给出了起点,这意味着在这种情况下,变量的值是2。因此,可以通过0xA5>>2找到起点。 第5位位置在这里是一个随机位置。表示它可以是6或7。其主要思想是在第二位之后将哪个位设置为1。我得把它提取出来

剩下的部分我怎么做

int result = (0xA5 >> 2) & 0x0F;
&运算符的真值表

&运算符的真值表


您可以使用掩码和&and操作:

a = 0xA5;
a = a >> OFFSET; //OFFSET 
mask = 0x0F; // equals 00001111
a = a & mask; 
在您的示例中,a=0xA5 10100101,偏移量为2

a>>2 a现在等于0x29 00101001 a&0x0F 00101001和 00001111=00001001=0x09
您可以使用掩码和&and操作:

a = 0xA5;
a = a >> OFFSET; //OFFSET 
mask = 0x0F; // equals 00001111
a = a & mask; 
在您的示例中,a=0xA5 10100101,偏移量为2

a>>2 a现在等于0x29 00101001 a&0x0F 00101001和 00001111=00001001=0x09
在本例中,我们将0或1个值放入数组中。之后,您可以随意处理数组

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv) {
    uint8_t value = 0xA5;
    unsigned char bytes[8];
    unsigned char i;

    for (i = 0; i < 8; i++) {
        bytes[i] = (value & (1 << i)) != 0 ? 1 : 0;
    }

    for (i = 0; i < 8; i++) {
        printf("%d", bytes[i]);
    }

    return 0;
}

在本例中,我们将0或1个值放入数组中。之后,您可以随意处理数组

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv) {
    uint8_t value = 0xA5;
    unsigned char bytes[8];
    unsigned char i;

    for (i = 0; i < 8; i++) {
        bytes[i] = (value & (1 << i)) != 0 ? 1 : 0;
    }

    for (i = 0; i < 8; i++) {
        printf("%d", bytes[i]);
    }

    return 0;
}

假设您正在处理变量的无符号int。 您必须构造适当的掩码

假设您想要从位置x到位置y的位,掩码中需要有y-x+1个1s

你可以通过-

int digits = y - x + 1;
unsigned int mask = 1u << digits - 1;
最后应用掩码以移除高位-

result = result & mask;

假设您正在处理变量的无符号int。 您必须构造适当的掩码

假设您想要从位置x到位置y的位,掩码中需要有y-x+1个1s

你可以通过-

int digits = y - x + 1;
unsigned int mask = 1u << digits - 1;
最后应用掩码以移除高位-

result = result & mask;

如果需要偏移量X中的位,则右移X

如果你想要Y位,那么移位后的掩码将是2到Y的幂减1,例如4位,2到4的幂是16,减去1是15,这是1111二进制。这可以通过使用Y位左移位并减去1来实现

但是,如果要计算所需位中的零数,则不需要掩蔽,只需右移。循环Y次,每次将1向左移动一步,并使用位和检查值是否为零。如果是,则增加一个计数器。在循环结束时,计数器是零的数目

要将其全部放在代码中:

// Count the number of zeros in a specific amount of bits starting at a specific offset
// value is the original value
// offset is the offset in bits
// bits is the number of bits to check
unsigned int count_zeros(unsigned int value, unsigned int offset, unsigned int bits)
{
    // Get the bits we're interested in the rightmost position
    value >>= offset;

    unsigned int counter = 0;  // Zero-counter
    for (unsigned int i = 0; i < bits; ++i)
    {
        if ((value & (1 << i)) == 0)
        {
            ++counter;  // Bit is a zero
        }
    }

    return counter;
}

结果应该是2。是的。

如果需要偏移量X中的位,则向右移位X

如果你想要Y位,那么移位后的掩码将是2到Y的幂减1,例如4位,2到4的幂是16,减去1是15,这是1111二进制。这可以通过使用Y位左移位并减去1来实现

但是,如果要计算所需位中的零数,则不需要掩蔽,只需右移。循环Y次,每次将1向左移动一步,并使用位和检查值是否为零。如果是,则增加一个计数器。在循环结束时,计数器是零的数目

要将其全部放在代码中:

// Count the number of zeros in a specific amount of bits starting at a specific offset
// value is the original value
// offset is the offset in bits
// bits is the number of bits to check
unsigned int count_zeros(unsigned int value, unsigned int offset, unsigned int bits)
{
    // Get the bits we're interested in the rightmost position
    value >>= offset;

    unsigned int counter = 0;  // Zero-counter
    for (unsigned int i = 0; i < bits; ++i)
    {
        if ((value & (1 << i)) == 0)
        {
            ++counter;  // Bit is a zero
        }
    }

    return counter;
}

结果应该是2。是哪个。

你知道位屏蔽吗?关于按位and运算符&?对于某个值,我知道如何提取。但在运行时,我们如何提取…使用变量作为掩码?并在运行时为变量分配正确的掩码?与移位相同,使用变量。您可以在运行时迭代不同的掩码,以便掩码检查被测数字中的所有位位置。如果这些int变量限制为一个字节,另一种方法可以是使用常量查找表来获得适当的掩码。您知道位掩码吗?关于按位and运算符&?对于某个值,我知道如何提取。但在运行时,我们如何提取…使用变量作为掩码?并在运行时为变量分配正确的掩码?与移位相同,使用变量。您可以在运行时迭代不同的掩码,以便掩码检查被测数字中的所有位位置。如果这些int-vars限制为一个字节,另一种方法是使用const查找表来获得适当的掩码。虽然此代码段可以解决此问题,确实有助于提高你的文章质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。还请尽量不要用解释性注释挤满你的代码,这会降低代码和解释的可读性!这是一个特殊的例子。我想对随机值这样做。这段代码可以解决这个问题

ion,确实有助于提高您的帖子质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。还请尽量不要用解释性注释挤满你的代码,这会降低代码和解释的可读性!这是一个特殊的例子。我想对随机值这样做。第5位的Istead也可以是第6位&&是逻辑and,按位and是&。首先,位2到5是四位。其次,您使用的是逻辑and运算符。&&掩码的结果将始终为1。&&是逻辑and,按位and是&。首先,位2到5是四位。其次,您使用的是逻辑and运算符。&&掩码的结果总是1。实际上,我们对变量位没有任何控制。我的意思是可能是4,5。。。但它是偏移后下一个1的位置如果目标是在偏移位之后提取第一个设置位,只需使用whilevalue并检查每个位是否已设置。当位设置为break时,否则继续循环。@Salim当你说下一个1的位置时,你不是指前一个1位吗?因为对于输入0xa5,我们只计算一位,因为位0是1。下一个1的规则是什么?如果你的例子中有1001,那就是第二个1,但是如果你有1010呢?还是1100?还是1000?请编辑您的问题,详细说明实际、具体和所有要求。如果可能的话,添加更多的例子。实际上,我们对变量位没有任何控制。我的意思是可能是4,5。。。但它是偏移后下一个1的位置如果目标是在偏移位之后提取第一个设置位,只需使用whilevalue并检查每个位是否已设置。当位设置为break时,否则继续循环。@Salim当你说下一个1的位置时,你不是指前一个1位吗?因为对于输入0xa5,我们只计算一位,因为位0是1。下一个1的规则是什么?如果你的例子中有1001,那就是第二个1,但是如果你有1010呢?还是1100?还是1000?请编辑您的问题,详细说明实际、具体和所有要求。如果可能的话,加上更多的例子。这里y的位置可以改变。基本上,我的意思是从第X个位置到下一个位置的零的数量,值为1。@Salim你的问题没有说清楚。我认为你应该把它作为一个单独的问题来发布,适当地显示细节,因为这已经得到了很多用户的充分回答。@Ayan:我在我的问题中已经有了这个问题,主要思想是在第二位之后的哪个位设置为1。我得把它摘录出来。我不知道确切的编辑时间,但编辑后问题发生了重大变化。我强烈建议发布一个单独的问题。我可以编辑我的答案以适应您的更改,但这对其他答案不公平,并且让这些答案与问题的新版本不一致。您可以回滚此问题,然后发布新问题。我相信没有人会介意类似但不同的问题。只要确保你用足够的例子和/或措辞清晰的描述清楚意图。在这里,位置y可以改变。基本上,我的意思是从第X个位置到下一个位置的零的数量,值为1。@Salim你的问题没有说清楚。我认为你应该把它作为一个单独的问题来发布,适当地显示细节,因为这已经得到了很多用户的充分回答。@Ayan:我在我的问题中已经有了这个问题,主要思想是在第二位之后的哪个位设置为1。我得把它摘录出来。我不知道确切的编辑时间,但编辑后问题发生了重大变化。我强烈建议发布一个单独的问题。我可以编辑我的答案以适应您的更改,但这对其他答案不公平,并且让这些答案与问题的新版本不一致。您可以回滚此问题,然后发布新问题。我相信没有人会介意类似但不同的问题。只要确保你用足够的例子和/或措辞清晰的描述清楚目的就行了。对于你提到的问题,有一个解决方案是可能的,而不需要实际使用循环。正如你所知。@Ayan没有循环我们怎么办?就像我之前说的,你需要问一个单独的问题。对于你提到的问题,有一个不使用循环的解决方案。正如你所知。@Ayan没有循环我们怎么办?就像我之前说的,你需要问一个单独的问题。