将 int 中的最后 10 位左移

scy*_*y17 1 c bitwise-operators byte-shifting

我需要实现一个向左循环 int 的最后 10 位的函数。

所以如果 int 有价值

0b 1111 0000 0000 0000 0000 1100 1100 0000
Run Code Online (Sandbox Code Playgroud)

左旋转 2 会给我们

0b 1111 0000 0000 0000 0000 1111 0000 0000
Run Code Online (Sandbox Code Playgroud)

再向左旋转 1 会得到

0b 1111 0000 0000 0000 0000 1110 0000 0001
Run Code Online (Sandbox Code Playgroud)
  • ptr- 指向我们想要旋转的给定 int 的指针
  • n- 我们想要旋转多少次
void leftRotateLast10Digits(int * ptr, int n) {

}
Run Code Online (Sandbox Code Playgroud)

我知道如果我们想旋转整个 int 该怎么做,但我不知道如何只旋转最后 10 位数字。我认为左旋转一个 int,它看起来像下面这样。但我仍然不明白如何只旋转最后 10 位数字。

void leftRotate(int * ptr, int n) {
    int DROPPED_MSB;
    int INT_BITS = sizeof(int) * 8 - 1;
    int num = *ptr;

    // The effective rotation
    n %= INT_BITS;

    while(n) {
        DROPPED_MSB = (num >> INT_BITS) & 1; 

        // Left rotate num by 1 and set its dropped MSB as new LSB
        num = (num << 1) | DROPPED_MSB;
        n--;
    }
    *ptr = num;
}
Run Code Online (Sandbox Code Playgroud)

chu*_*ica 5

我不知道如何只处理最后 10 位数字

将 10 位与其余位隔离。

旋转 10 位(我会跳过循环while)。

“或”将 10 位放回到int.


(让我们使用“最少”而不是“最后”)

void leftRotateLeast10Digits(int *ptr, int n) {
  int value = *ptr;
  int ls10bits = value & 0x3FF;
  value ^= ls10bits;  // zero out the 10 LS bits.
  
  // If `n` outside [0...9] range needed
  n %= 10;
  if (n < 0) n += 10;

  // move LS bits left `n` times` and MS bits right `10-n` times.
  int rotated = (ls10bits << n) | (ls10bits >> (10-n));
  rotated &= 0x3FF;

  value |= rotated;
  *ptr = value;
}
Run Code Online (Sandbox Code Playgroud)

支持 16 位需要一些额外的工作intint ls10bits-->int_least32_t ls10bits轻松处理<<.
我建议当结果不是陷阱时,这也适用于罕见的非 2 补码。


提示:位操作和移位最好使用无符号类型和数学来完成,而不是int.