我今天接受了采访,他们要求我写两个“C”函数,一个用于提取单个位,另一个用于从字符中提取一系列位。我花了一段时间想出了这些方法。
int extractBit(char byte, int pos) {
assert( (pos >= 0) && (pos < 8) );
return ( ( byte & (1<<pos) ) >> pos);
}
char extractBitRange(char byte, int startingPos, int offset) {
assert( ( (startingPos + offset) >= 0) && ( (startingPos + offset) < 8) );
return ( byte >> startingPos ) & ~(0xff << (offset + 1));
}
但是面试官一直在问我是否可以进一步加快代码(就cpu周期而言)以及是否有任何优化范围可以实现它。 我显然不合适,我很想知道你会怎么做?
答案 0 :(得分:18)
在extractBit中,如果您先移动,则可以使用1
而不是(1<<pos)
进行屏蔽。
考虑到pos是函数的参数,可以节省计算量。
return (byte >> pos) & 1;
在第二个函数中,我断言startingPos
和offset
都是正数而不是断言它们的和是正数,这样就更有道理了。
答案 1 :(得分:5)
查找表?
答案 2 :(得分:3)
你在比特范围内做的另一个:
~(0xff << (offset + 1))
-->
~(0xfe << offset)
因为<< 1
不过是*2
,你可以对你的常量进行这个操作(如果你在单元字节上操作就是摆脱LSB)。
答案 3 :(得分:3)
您可以通过先向右移动然后屏蔽该位来加速第一个功能:
int extractBit(char byte, int pos) {
return (byte >> pos) & 0x01;
}
这可以节省您一次操作。
对于第二个问题,我假设startingPos
是要提取的块的第一位,offset
是您需要的块中的位数。
然后你可以用这个:
char extractBitRange(char byte, int startingPos, int offset) {
return (byte >> startingPos) & ((1 << offset)-1);
}
当然,您必须小心范围,就像在代码中一样。
编辑:如果您希望extractBitRange(b,i,0)
表现得像extractBit(b,i)
并在位置i处提取一个位,则此变体会执行此操作:
return (byte >> startingPos) & ((2 << offset) - 1);
答案 4 :(得分:0)
int extractBit(int byte, int pos)
{
if( !((pos >= 0) && (pos < 16)) )
{
return 0;
}
return ( ( byte & (1<<pos) ) >> pos);
}
int _tmain()
{
// TODO: Please replace the sample code below with your own.
int value;
signed int res,bit;
value = 0x1155;
printf("%x\n",value);
//Console::WriteLine("Hello World");
//fun1();
for(bit=15;bit>=0;bit--)
{
res =extractBit(value,bit);
printf("%d",res);
}
return 0;
}
答案 5 :(得分:-3)
如果您想快速获得,可以使用查找表。我猜这就是面试官的目的(作为“我怎样才能让这更快”的最终答案)。
基本上,这意味着您事先创建了一个巨大的表,将每个可能的参数组合映射到正确的结果。例如,你有:
byte = 0x0, pos = 0, result = 0
byte = 0x0, pos = 1, result = 0
...
byte = 0x1, pos = 0, result = 1
显然,这需要放入有效的c数据结构(数组,由byte和pos索引)。这将允许您在函数中根据您选择的索引方案返回数组中的位置。
对于第一个函数,这不会占用太多内存。我们讨论的是一个字节的值(一个字节可以有256个不同的值)乘以8个可能的值来启动pos,这使得一个2048的数组。
对于第二个功能,这实际上会占用更多空间。你需要将起始和结束pos的所有可能值乘以256倍(请记住,起始和结束pos都有非法组合)。
我猜测面试官只是想让你回答这将是一种加快速度的方法,然后提供上述想法,试图估计它会花费多少空间与节省的时间。