C #表示数字x所需的位数
我目前正在尝试编写一个算法,确定代表一个数字x需要多少位。我的实现将使用c语言。 尽管有一些捕获,但我仅限于位运算符{~,&,^,|,+,}。此外,我不能使用任何类型的控制流(if、while、for)。 我最初的方法是从左到右检查二进制数字,并查找第一个“1”出现的位置。考虑到我的限制,我不知道该如何处理这个问题。 我使用的数字可以视为无符号整数。因此00110只需要3位 我想知道是否有一个更简单/更干净的方法来做到这一点,我错过了吗? 或者如果有人能给出一些提示 基本上,我尝试在没有while循环的情况下实现这一点:C #表示数字x所需的位数,c,binary,bit-manipulation,C,Binary,Bit Manipulation,我目前正在尝试编写一个算法,确定代表一个数字x需要多少位。我的实现将使用c语言。 尽管有一些捕获,但我仅限于位运算符{~,&,^,|,+,}。此外,我不能使用任何类型的控制流(if、while、for)。 我最初的方法是从左到右检查二进制数字,并查找第一个“1”出现的位置。考虑到我的限制,我不知道该如何处理这个问题。 我使用的数字可以视为无符号整数。因此00110只需要3位 我想知道是否有一个更简单/更干净的方法来做到这一点,我错过了吗? 或者如果有人能给出一些提示 基本上,我尝试在没有whil
int result = 0;
while (x >>= 1) {
result += 1;
}
return result;
演示如何在没有控制流的情况下执行此操作
unsigned int v; // 32-bit value to find the log2 of
register unsigned int r; // result of log2(v) will go here
register unsigned int shift;
r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF ) << 3; v >>= shift; r |= shift;
shift = (v > 0xF ) << 2; v >>= shift; r |= shift;
shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
r++;
无符号整数v;//32位值,用于查找
寄存器无符号整数r;//log2(v)的结果将显示在此处
寄存器无符号整数移位;
r=(v>0xFFFF)>=r;
移位=(v>0xFF)>=移位;r |=移位;
移位=(v>0xF)>=移位;r |=移位;
移位=(v>0x3)>=移位;r |=移位;
r |=(v>>1);
r++;
我想他需要的是第一位计数器,而不是最后一位计数器。
由于该算法包含32位整数,因此需要对结果进行修正
unsigned int v; // 32-bit value to find the log2 of
register unsigned int r; // result of log2(v) will go here
register unsigned int shift;
r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF ) << 3; v >>= shift; r |= shift;
shift = (v > 0xF ) << 2; v >>= shift; r |= shift;
shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
return 32-r;
无符号整数v;//32位值,用于查找
寄存器无符号整数r;//log2(v)的结果将显示在此处
寄存器无符号整数移位;
r=(v>0xFFFF)>=r;
移位=(v>0xFF)>=移位;r |=移位;
移位=(v>0xF)>=移位;r |=移位;
移位=(v>0x3)>=移位;r |=移位;
r |=(v>>1);
返回32-r;
接受的答案实际上是错误的:例如,它输出5表示32..63(而不是6),输出4表示16..31(而不是5)。这就像取以2为底的对数并向下取整一样
正确的解决方案如下:
unsigned int v; // 32-bit value to find the log2 of
register unsigned int r; // result of log2(v) will go here
register unsigned int shift;
r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF ) << 3; v >>= shift; r |= shift;
shift = (v > 0xF ) << 2; v >>= shift; r |= shift;
shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
r++;
无符号整数v;//32位值,用于查找
寄存器无符号整数r;//log2(v)的结果将显示在此处
寄存器无符号整数移位;
r=(v>0xFFFF)>=r;
移位=(v>0xFF)>=移位;r |=移位;
移位=(v>0xF)>=移位;r |=移位;
移位=(v>0x3)>=移位;r |=移位;
r |=(v>>1);
r++;
注意r++请尝试:
// http://www.cs.northwestern.edu/~wms128/bits.c
int check_bits_fit_in_2s_complement(signed int x, unsigned int n) {
int mask = x >> 31;
return !(((~x & mask) + (x & ~mask))>> (n + ~0));
}
这个数字是整数还是浮点数?最大值和最小值是多少?签名还是未签名?@AbhijeetRastogi:是的,这是我为计算机架构课程解决的最后一个“难题”之一。我有各种类型的问题,像这样涉及位操作,我目前大约有80%的问题,这是最后一个我似乎无法着手解决的问题之一。@Adamless:数字被解释为无符号整数。在你的例子中,结果不应该从1开始吗?传递x=00110将返回2,因为第三次通过循环,x将等于000000,因此不会增加结果。如果您想查看更多“l33t”:
number>=1
:)请注意,他写道,我不能使用任何类型的控制流。
。帖子说没有控制流,我认为这意味着没有循环滚动循环意味着它不是循环:)即,没有分支:)@AntoineMathys这不是汇编,但许多汇编程序可以进行这种比较,然后在没有分支的情况下获得比较值。注意,在这种情况下,它只需要船旗国就可以进行,而不需要根据结果进行分支。(尽管编译器可能会决定分支,如果它认为分支更有效的话)。但不管怎样,问题是关于C的,他会接受它,因为当他查找