交换C中的数字位

时间:2009-07-28 07:48:37

标签: c bit-manipulation

在C采访中,我被要求将数字的前4位与最后4位交换。 (例如,1011 1110应为1110 1011.)

有人有解决方案吗?

15 个答案:

答案 0 :(得分:15)

如果你还没有看到或做过多苦苦挣扎,那么学习的好资源是:

答案 1 :(得分:8)

unsigned char c;

c = ((c & 0xf0) >> 4) | ((c & 0x0f) << 4);

答案 2 :(得分:6)

这种面试问题没有“正确答案”。有几种方法可以做到这一点(查找表,任何人?),并且需要讨论每种方式之间的权衡(可读性与性能对可移植性与可维护性之间的权衡)。

这个问题只是一个让你讨论上述问题的开场白,并确定你如何“深入”讨论这些问题。

答案 3 :(得分:3)

只需使用一个临时变量并将最后一位移入该变量,然后将该位移向该方向,并在tmp var中的位中结束屏蔽,您就完成了。


<强>更新 让我们添加一些代码然后你可以选择更具可读性的代码。

工作单线

unsigned int data = 0x7654;
data = (data ^ data & 0xff) | ((data & 0xf) << 4) | ((data & 0xf0) >> 4);
printf("data %x \n", data);

相同的代码,但有一些tmp vars

unsigned int data = 0x7654;

unsigned int tmp1 = 0;
unsigned int tmp2 = 0;

tmp1 = (0x0f&data)<<4;
tmp2 = (0xf0&data)>>4;
tmp1 = tmp1 | tmp2;

data = data ^ (data & 0xff); 

data = data | tmp1;

printf("data %x \n", data);

无论如何,一条衬里更短:)


<强>更新

如果你看一下gcc用-Os -S生成的asm代码,我的猜测是它们或多或少相同,因为在“编译器优化”部分中删除了开销。

答案 4 :(得分:2)

不需要临时变量,这样的事情应该这样做:

x = ((x & 0xf) << 4) | ((x & 0xf0) >> 4);

根据x的具体类型,存在潜在的陷阱。识别这个问题留给读者练习。

答案 5 :(得分:2)

C ++ - 类似伪代码(可以很容易地重写为不使用临时变量):

int firstPart = source & 0xF;
int offsetToHigherPart = sizeof( source ) * CHAR_BIT - 4;
int secondPart = ( source >> offsetToHigherPart ) & 0xF;
int maskToSeparateMiddle = -1 & ( ~0xF ) & ( ~( 0xF << offsetToHigherPart );
int result = ( firstPart << offsetToHigherPart ) | secondPart | (source & maskToSeparateMiddle);

这将需要定义CHAR_BIT。它通常在limits.h中,定义为8位,但严格来说是依赖于平台的,并且在头文件中根本没有定义。

答案 6 :(得分:2)

unsigned char b;
b = (b << 4) | (b >> 4);

答案 7 :(得分:1)

您是否在寻找比标准位移更聪明的东西?

(假设a是8位类型)

a = ((a >> 4) & 0xF)  + ((a << 4) &0xF0)

答案 8 :(得分:1)

x86汇编:

asm{
  mov AL, 10111110b
  rol AL
  rol AL
  rol AL
  rol AL
}

http://www.geocities.com/SiliconValley/Park/3230/x86asm/asml1005.html

答案 9 :(得分:0)

最简单的是(t是无符号):

t = (t>>4)|(t<<4);

但是如果你想混淆你的代码,或者交换其他位组合,你可以使用这个基础:

mask = 0x0F & (t ^ (t >> 4));
t ^= (mask | (mask << 4));

答案 10 :(得分:0)

/*swaping four bits*/
#include<stdio.h>

void printb(char a) {
    int i;
    for( i = 7; i >= 0; i--)
        printf("%d", (1 &  (a >> i)));
    printf("\n");
}

int swap4b(char a) {
    return ( ((a & 0xf0) >> 4) | ((a & 0x0f) << 4) );
}


int main()
{
    char a = 10;
    printb(a);
    a = swap4b(a);
    printb(a);
    return 0;
}

答案 11 :(得分:0)

这是完全交换位的方法,用于更改字节中的位字节序。

&#34; IIN&#34;实际上是一个整数,因为我用它来读取文件。我需要顺序中的位,我可以按顺序轻松读取它们。

// swap bits
iIn = ((iIn>>4) & 0x0F) | ((iIn<<4) & 0xF0); // THIS is your solution here.
iIn = ((iIn>>2) & 0x33) | ((iIn<<2) & 0xCC);
iIn = ((iIn>>1) & 0x55) | ((iIn<<1) & 0xAA);

在单个字节中只交换两个半字节,这是最有效的方法,在大多数情况下它可能比查找表更快。

我看到很多人在做转移,忘了在这里做掩饰。当有符号扩展时,这是一个问题。如果你有unsigned char的类型,它很好,因为它是一个无符号的8位数量,但是它会失败并且任何其他类型。

掩码不会增加开销,使用unsigned char,无论如何暗示掩码,任何体面的编译器都会删除不必要的代码并且已经存在了20年。

答案 12 :(得分:0)

在last和first之间进行通用n位交换的解决方案。 当总位小于2n时未验证。 这里7是char,31是整数。

unsigned char swapNbitsFtoL(unsigned char num, char nbits)
{
    unsigned char u1 = 0;
    unsigned char u2 = 0;

    u1 = ~u1;
    u1 &= num;
    u1 = (u1 >> (7 - (nbits - 1))); /* Here nbits is number of n=bits so I have taken (nbits - 1). */

    u2 = ~u2;
    u2 &= num;
    u2 = (u2 << (7 - (nbits - 1))); /* Here nbits is number of n=bits so I have taken (nbits - 1). */

    u1 |= u2; /* u1 have first and last swapped n bits with */

    u2 = 0;
    u2 = ~u2;
    u2 = ((u2 >> (7 - (nbits - 1))) | (u2 << (7 - (nbits - 1))));
    bit_print(u2);
    u2 = ~u2;
    u2 &= num;

    return (u1 | u2);
}

答案 13 :(得分:-1)

我在这方面的技能是新的,因此未经证实,所以如果我错了,那么我会学到新的东西,这至少是Stack Overflow的一部分。

bitmask和XOR也会工作吗?

喜欢这样吗?

var orginal=
var mask =00001110 //I may have the mask wrong
var value=1011 1110
var result=value^mask;

我可能会误解事情,请原谅我,如果我已经搞砸了。

答案 14 :(得分:-1)

#include <stdio.h>
#include <conio.h>
#include <math.h>
void main() { 
    int q,t,n,a[20],j,temp;
    int i=0;
    int s=0;
    int tp=0;
    clrscr();
    printf("\nenter the num\n");
    scanf("%d",&n);
    t=n;
    while(n>0) {
        a[i]=n%2;
        i++;
        n=n/2;
    }
    printf("\n\n");
    printf("num:%d\n",t);
    printf("number in binary format:");
    for(j=i-1;j>=0;j--) {
        printf("%d",a[j]);
    }
    printf("\n");
    temp=a[i-1];
    a[i-1]=a[0];
    a[0]=temp;
    printf("number in binary format wid reversed boundary bits:");
    for(j=i-1;j>=0;j--) {
        printf("%d",a[j]);
    }
    printf("\n");
    q=i-1;
    while(q>=0) {
        tp=pow(2,q);
        s=s+(tp*a[q]);
        q--;
    }
    printf("resulatnt number after reversing boundary bits:%d",s);
    printf("\n");
    getch();
}