在C采访中,我被要求将数字的前4位与最后4位交换。 (例如,1011 1110应为1110 1011.)
有人有解决方案吗?
答案 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();
}