C语言 向左旋转整数中的最后 10 位



我需要实现一个向左旋转整数的最后 10 位的函数。

所以如果一个 int 有值

0b 1111 0000 0000 0000 0000 1100 1100 0000

向左旋转 2 会给我们

0b 1111 0000 0000 0000 0000 1111 0000 0000

再向左旋转 1 将给出

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

如果我们想旋转整个 int,我明白该怎么做,但我不确定如何只对最后 10 位数字进行操作。我认为要向左旋转一个整数,它看起来像下面这样。但是,我仍然不明白如何只旋转最后 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;
}

我不确定如何只对最后 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;
}

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


提示:位操作和移位最好使用无符号类型和数学来完成,而不是像int这样的有符号类型和数学。

一种相对简单的方法是将整数分成两部分:应该旋转的 10 位和其他不应该旋转的(高)位。然后,在旋转适当的部分后,使用按位 OR 操作恢复其他位:

void leftRotate(int* ptr, int n)
{
int mask = 0x03FF; // Mask for lower 10 bits;
int DROPPED_MSB;
int INT_BITS = 10; // Only work with 10 bits
int num = *ptr & mask; // Extract JUST low 10 bits
int top = *ptr & ~mask; // Save all the OTHER bits
n %= INT_BITS; // The effective rotation
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 | top; // Restore the saved upper bits
}

最新更新