【问题标题】:shift bits from a byte into an (array)将位从一个字节转移到一个(数组)
【发布时间】:2011-09-29 14:52:57
【问题描述】:

我解决了这个问题,但不知道如何以一种好的方式发布它,所以我编辑了这个帖子并将解决方案放在它的末尾。


在 C 中需要帮助,尝试将字节位转换为相反的顺序。

我想让Step1[] = {1,0,0,1,0,0,0,0}; 变成{0,0,0,0,1,0,0,1}

void Stepper(void)
{
static uint8_t Step1[] = {1,0,0,1,0,0,0,0};
BridgeControl(Step1);
}

void BridgeControl(unsigned char *value)
{
    uint8_t tempValue;
    uint8_t bit = 8;
    uint8_t rev = 1;

    if (rev) // CW otherwise CCW
    {
        tempValue = *value;
        do{

        if(tempValue) // Right-shift one
            tempValue = 1 >> 1;
        else
            tempValue = 0 >> 1;

        }while(--bit, bit);
        *value = tempValue;
    }

我知道 bridcontrol 完全错误,在这里我需要帮助! 亲切的问候


新代码:

void BridgeControl(uint8_t *value)
{
    // For example, initial value could be 1001000 then I
    // would like the outcome to be 00001001

    uint8_t tempValue;

    uint8_t bit = 3;
    uint8_t rev = 1;

    if (rev) // CW otherwise CCW
    {
        tempValue = *value; //so... its 0b10010000
        do{
            tempValue >>=1; //1st this produce 01001000
            tempValue = 0 >> 1; //1st this produce 0010 0100
                                //2nd time produce 0001 0010
                                //3d time produce 0000 1001
        }while(--bit, bit);
    *value = tempValue;
    }
    M1BHI = value[7];
    M1BLI = value[6];
    M1AHI = value[5];
    M1ALI = value[4];
    M2BHI = value[3];
    M2BLI = value[2];
    M2AHI = value[1];
    M2ALI = value[0];
}

解决方案:

void BridgeControl(uint8_t value)
{
    uint8_t tempvalue[8];
    uint8_t i = 8;
    uint8_t cont;
    cont = value;
    do{
        value = value >> i-1;
        value = value & 1;
        tempvalue[8-i] = value;
        value = cont;
    }while(--i,i);

    M1BHI = tempvalue[7]; 
    M1BLI = tempvalue[6]; 
    M1AHI = tempvalue[5]; 
    M1ALI = tempvalue[4]; 
    M2BHI = tempvalue[3]; 
    M2BLI = tempvalue[2]; 
    M2AHI = tempvalue[1]; 
    M2ALI = tempvalue[0]; 


}

如果我想要数组中位的相反顺序,只需将tempvalue[8-i] 更改为tempvalue[i-1]

【问题讨论】:

  • 为什么人们投反对票?这是一个合法的问题,并且 OP 在发布到这里之前已经明显地尝试了一些东西(它在问题中!)。
  • 您谈论的是位,但展示了一个整数数组的示例。我对您要做什么感到困惑。通过该示例,您似乎正在尝试反转整数数组的顺序。
  • 这是 C# 吗?看起来更像是 C# 和 C (uint8_t, char*) 的混合体......
  • 这是有效的 c# 代码吗?对我来说它看起来像 c...可能是错误的标签?
  • 他在不安全的 C# 代码中使用了指针。他正在尝试用 C# 编写 C/C++ 代码。各有各的...

标签: c bit-manipulation


【解决方案1】:

您的变量名称听起来像是在尝试使用硬件。所以我猜你真的想在一个字节变量中移动位,而不是在一个 int 数组中。

此语句将字节中的位反转:

byte reversedVal = (byte) (val & 1 << 7
                          + val & 2 << 5
                          + val & 4 << 3
                          + val & 8 << 1
                          + val & 16 >> 1
                          + val & 32 >> 3
                          + val & 64 >> 5
                          + val & 128 >> 7);

如果你真的想反转一个 int 数组,你可以使用 scottm 建议的 LINQs Reverse 方法,但这可能不是最快的选择。

【讨论】:

  • 这样的代码有点太聪明了。除非性能被证明是一个问题,否则您应该首先使用 Array.Sort。
  • @wllmsaccnt:我这里不是在谈论数组。
  • 对,但他已经在数组中的示例中得到了他的值。他最好的选择是使用易于理解的内置函数,而不是位移操作。
  • @wllmsaccnt:视情况而定。我认为字节数组代码是他(失败)尝试将字节反转的位。但也许他会随时澄清他真正的担忧:)
  • 顺便说一句,你是对的。在我的硬件上,您的代码比 Array.Sort 快不到 11 倍。
【解决方案2】:

Array.Reverse() 简单粗暴:

byte[] step1 = new {0,1,0,1};

var reversed = Array.Reverse(step1);

如果真的需要交换字节序,可以看答案here

【讨论】:

  • 请注意,Array.Reverse 实际上改变了现有数组。如果您想要一个与数组相反的新序列而不更改原始数组,请使用 LINQ 序列运算符库中的 Reverse() 扩展方法。
  • @Eric Lippert,很高兴知道。 Reverse() 扩展方法只是反向迭代数组,对吗?如果我在哪里打电话array.Reverse().ToArray() 那会变异吗?
  • 这不会改变原始数组。相反,它将创建一个包含反转状态的 second 数组。 (另外,我注意到你的代码是错误的—— Array.Reverse 是返回无效的。)
【解决方案3】:
void BridgeControl(unsigned char values[], int size){
    unsigned char *head, *end, wk;
    for(head = values, end = values + size - 1; head < end; ++head, --end){
        wk = *head;
        *head = *end;
        *end = wk;
    }
}
void Stepper(void){
    static unsigned char Step1[] = {1,0,0,1,0,0,0,0};
    BridgeControl(Step1, sizeof(Step1));
}

【讨论】:

    【解决方案4】:
    // changed the parameter to suit the type of members of array
    void BridgeControl(uint8_t *value)
    {
        uint8_t tempvalue;
    
        // only need to loop till midway; consider the two sides as lateral images of each other from the center
        for (int i=0; i < 8/2; i++)
        {
            // preserve the current value temporarily
            tempvalue = *[value + i];
            // set the current value with the value in the mirrored location
            // (8th position is the mirror of 1st; 7th position is the mirror of 2nd and so on)
            *[value + i] = *[value + (7 - i)];
            // change the value in the mirrored location with the value stored temporarily
            *[value + (7 - i)] = tempvalue;
        }
    
    }
    // you may want to use sizeof(uint8_t) * (7 - i) instead of (7 - i) above
    

    【讨论】:

      【解决方案5】:
      //Exempel of input going to function: int value = 0b10010000; 
      
      void BridgeControl(uint8_t value uint8_t dir) 
      { 
          uint8_t tempvalue[8]; 
          uint8_t i = 8; 
          uint8_t cont; 
          cont = value;
       if (dir){
          do{ 
              value = value >> i-1; 
              value = value & 1; 
              tempvalue[8-i] = value; 
              value = cont; 
          }while(--i,i); 
       }
       else{
          do{ 
              value = value >> i-1; 
              value = value & 1; 
              tempvalue[i-1] = value; 
              value = cont; 
          }while(--i,i); 
       }
          M1BHI = tempvalue[7];  
          M1BLI = tempvalue[6];  
          M1AHI = tempvalue[5];  
          M1ALI = tempvalue[4];  
          M2BHI = tempvalue[3];  
          M2BLI = tempvalue[2];  
          M2AHI = tempvalue[1];  
          M2ALI = tempvalue[0];  
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-15
        • 1970-01-01
        • 2023-03-29
        • 2012-08-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多