【问题标题】:How to rotate bits to the left and add rotated bits to the right如何向左旋转位并向右添加旋转位
【发布时间】:2017-03-05 07:56:10
【问题描述】:

我正在尝试让我的程序运行,我将位向左移动并将移动的位添加到右侧。例如00111000,如果你把它向左移动4个位置,结果应该是10000011。我怎样才能使这项工作,我知道我需要使用按位或。我在下面添加了主要功能。

#include <stdio.h>
#include <stdlib.h>

void printbits(int b){
    int i;
    int s = 8 * (sizeof b) - 1; /* 31 if int is 32 bits */
    for(i=s;i>=0;i--)
    putchar( b & 1<<i ? '1' : '0');
}



int main(){
    char dir; /* L=left R=right */
    int val, n, i;

    scanf("%d %d %c",&val, &n, &dir);
    printbits(val);putchar('\n');
    for (i=0; i<10; i++){
    if (dir=='L' || dir =='l')
      rotateLeft(&val, n);
    else
      rotateRight(&val,n);      
    printbits(val); putchar('\n');
    }
return;
}

这是 rotateLeft 和 rotateRight 函数。

#include <stdio.h>
#include <stdlib.h>

void rotateLeft(int *val, int N){
    int num = val[0];
    int pos = N;

    int result = num << pos;


}

void rotateRight(int *val, int N){
    int num = val[0];
    int pos = N;

    int result = num >> pos;


}

【问题讨论】:

  • 这个“将移位的位加到右边”是什么意思?左右移动然后求和?
  • A similar question。请注意,如果您在签名的int 的符号位中折腾,那么您是在没有手电筒的情况下走在漆黑的悬崖边缘。
  • @BenceKaulics 如果将其向左移动 4 个位置,则应将这些 1 添加到右侧。我很难解释,对不起:S
  • @Sullivan 没问题,我应该通过你的例子理解它。

标签: c algorithm rotation bit-manipulation


【解决方案1】:
MSB = (n >> (NUM_OF_BITS_IN_INT - 1))
n = (n << 1) | MSB;

n 左旋转 1 位。

您只是对 MSB 不屑一顾,而不是 添加它回到 LSB 位置。

【讨论】:

  • 感谢您的回答,什么是 MSB?
  • MSB :最高有效位。 LSB:最低有效位。所以,MSB 和 LSB 分别是最左边和最右边的位。
【解决方案2】:

使用此链接中的函数执行旋转:

https://en.wikipedia.org/wiki/Circular_shift

【讨论】:

    【解决方案3】:

    这是一个经过测试且未经优化的解决方案来完善您的源代码:

    void rotateLeft(int *val, int N){
        unsigned int num = val[0];
        int pos = N;
    
        unsigned int part1 = num << pos;
        unsigned int part2 = (num >> ((sizeof(val[0])*CHAR_BIT)-pos));
    
        if (N != 0) {
            val[0] = part1 | part2;
        }
    }
    
    void rotateRight(int *val, int N){
        unsigned int num = val[0];
        int pos = N;
    
        unsigned int part1 = num >> pos;
        unsigned int part2 = (num << ((sizeof(val[0])*CHAR_BIT)-pos));
    
        if (N != 0) {
            val[0] = part1 | part2;
        }
    }
    

    为防止在右移期间自动进位,您必须 将 value 视为 unsigned int。

    为防止 N = 0 干扰,仅当 (N != 0) 时才将结果分配给条目。 (见帖子ROL / ROR on variable using inline assembly in Objective-C的备注)

    【讨论】:

    • @piquard 这部分是做什么的?如果 (N != 0) { val[0] = part1 |第二部分;
    • @Sullivan 输入中的值仅在订购 ROR 或 ROL 时更新(意味着 N != 0)。注意:这两个函数都可以合并,因为 N 的负值将执行相反的操作。
    • 我明白了,为什么你需要 OR 第 1 部分和第 2 部分?
    • @Sullivan 抱歉,我解释得不够充分。第 1 部分是移位(左或右)但填充 0 的数字,第 2 部分是在第 1 部分填充位之前移位的丢失位。最后的 OR 合并到一组位。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    相关资源
    最近更新 更多