【问题标题】:Understanding unsigned char left rotation in C了解 C 中的 unsigned char 左旋转
【发布时间】:2018-12-02 05:08:15
【问题描述】:

我需要使用 C 将 unsigned char 数组左旋转 1。我在互联网上发现了以下代码,我很难理解。我从没想过它会这么复杂(至少对我来说是这样)。有人可以帮我理解这里的代码到底发生了什么吗?

/* accept an unsigned char array, with size and rotate it left by one 1 position*/

static void rotate_left( unsigned char * input, int size)
{
    int i, carry_back= 0;

    if(input[size-1] & (1<<(CHAR_BIT - 1)))
    {
        carry_back = 1;
    }

    for(i= size-1; i>=0; i--)
    {
        unsigned char carry = 0;

        if(i!= 0 && (input[i-1] & (1<<(CHAR_BIT - 1))))
        {
            carry = 1;
        }
        input[i] <<= 1;
        input[i] |= carry;

    }

    if(carry_back == 1)
    {
        input[0] |= 0x01;
    }

}

【问题讨论】:

  • 尝试用笔和纸逐步完成。或者也许使用调试器逐步完成。
  • 在大多数系统上,CHAR_BIT 是 8,所以 1&lt;&lt;(CHAR_BIT - 1) 与 1&lt;&lt;7 相同,即 0x80。换句话说,它是unsigned char 的最高有效位的位掩码。
  • by: 向左旋转1个位置,你的意思是旋转一位还是一个数组项?

标签: c arrays rotation bit-manipulation unsigned


【解决方案1】:

此代码将大小为size 的无符号chars 的序列左移一位,由input 指针表示。该序列从后到前排列,如little endian 系统。

为了做到这一点,您从序列的后面开始,向左工作,每次提取最高有效位以移位或“进位”到先前的unsigned char。最高有效位的提取是使用以下公式完成的:input[i] &amp; (1&lt;&lt;(CHAR_BIT - 1)) 这相当于通过使用按位 &amp; 运算符“屏蔽”该位来检查该位。每个单独的unsigned char 也被左移,其最高有效位被删除。

作为最后一步,算法将最后一个unsigned char 的最高有效位(以carry_back 表示)推入初始unsigned char 的最低有效位,从而完成轮换。

我们为什么要在i!=0 &amp;&amp; (input[i-1] &amp; (1&lt;&lt;CHAR_BIT -1))) 中检查input[i-1]?

因为顺序是这样排列的,位置i左侧的下一个unsigned char位于位置i+1,所以i-1实际上是位置i的右侧。

为什么我们要在 input[i] 和最后的进位之间做 OR?

我们这样做是为了完成旋转,使移位循环。

【讨论】:

  • 感谢您提供详细信息。我仍然没有清楚地理解以下部分,尽管我觉得你的解释几乎就在那里 - if(i!=0 && (input[i-1] & (1
  • 谢谢。这很清楚。所以,按照这个,下面的版本也应该可以工作——你怎么看?静态无效旋转左(无符号字符*输入,整数大小){整数进位= 0;诠释我; for (i = size - 1; i >=0; i--) { int next = (input[i] & 1) ? 0x80:0;输入[i] = 进位 | (输入[i]
  • @Subzero 你的循环的问题是它没有处理carry_back 位。当设置最后一个字节的最高有效位时,正确地将carry 设置为1。
猜你喜欢
  • 1970-01-01
  • 2013-07-21
  • 1970-01-01
  • 1970-01-01
  • 2020-10-11
  • 2011-07-04
  • 2012-05-06
  • 2020-05-03
  • 2017-10-30
相关资源
最近更新 更多