Повернуть влево последние 10 бит в int - PullRequest
0 голосов
/ 09 июля 2020

Мне нужно реализовать функцию, которая вращает влево последние 10 бит int.

Итак, если 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 цифр только. Я думаю, что левый поворот 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;
}

Ответы [ 2 ]

4 голосов
/ 09 июля 2020

Я не уверен, как это сделать только для последних 10 цифр

Изолировать 10 бит от остальных.

Повернуть 10 бит (I 'Я бы пропустил while l oop).

«Или» 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-битного int требуется дополнительная работа. int ls10bits -> int_least32_t ls10bits, чтобы легко обрабатывать <<. Я бы предположил, что это также работает для редких дополнений, отличных от 2, когда результат не является ловушкой.

Совет: битовые манипуляции и сдвиги лучше всего выполнять с типами и математикой без знака , а не с типами со знаком , такими как int.

0 голосов
/ 09 июля 2020

Относительно простой способ сделать это - разделить целое число на две части: 10 бит, которые должны быть повернуты, и другие (верхние) биты, которые не должны вращаться. Затем, после поворота соответствующей части, восстановите другие биты, используя операцию побитового ИЛИ:

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
}
...