在C中反转整数的位
我试图在C程序中反转整数的位。尽管我已经看过了,但我还是无法理解所编写的大部分代码。我注意到我的代码与 但我无法识别以下代码的问题:在C中反转整数的位,c,bit-manipulation,C,Bit Manipulation,我试图在C程序中反转整数的位。尽管我已经看过了,但我还是无法理解所编写的大部分代码。我注意到我的代码与 但我无法识别以下代码的问题: #include <stdio.h> #include <stdlib.h> unsigned int reverse_bits(unsigned int num) { unsigned int reverse_num = 0; /* initialize the result*/ unsigned int count = sizeof(
#include <stdio.h>
#include <stdlib.h>
unsigned int reverse_bits(unsigned int num)
{
unsigned int reverse_num = 0; /* initialize the result*/
unsigned int count = sizeof(unsigned int) * 8 - 1; /* counter to track the number of bits in the integer*/
while (num != 0)
{
unsigned int last_bit = num & 1; /* get the right-most bit*/
reverse_num = reverse_num | last_bit; /* add that bit to the right-most bit of the desired reversed bits*/
reverse_num = reverse_num << 1; /* shift the reversed bits left*/
num = num >> 1; /* shift the original bits right*/
count--;
}
reverse_num = reverse_num << count; /* If the original bits have only 0
s then shift the remaining bits left*/
return reverse_num;
}
int main()
{
reverse_bits(1);
}
#包括
#包括
无符号整数反向_位(无符号整数数值)
{
unsigned int reverse_num=0;/*初始化结果*/
unsigned int count=sizeof(unsigned int)*8-1;/*计数器,用于跟踪整数中的位数*/
while(num!=0)
{
unsigned int last_bit=num&1;/*获取最右边的位*/
reverse_num=reverse_num | last_bit;/*将该位添加到所需反转位的最右位*/
reverse_num=reverse_num>1;/*将原始位右移*/
计数--;
}
reverse_num=reverse_num虽然您没有提供执行打印的代码部分,但很明显您混合了int
和unsigned int
对于printf()
函数族,unsigned int
的说明符是%u
,因此如果要打印输出,应使用:
printf("%u\n", reverse_bits(1));
除此之外,您的代码是正常的,此外,请注意,如果机器使用2的补码和32位作为int,则-2147483648=100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
是如何观察到它返回负值的?无符号int
仅为在您的代码中使用…我假设您试图使用%d
将返回值打印为int
,但这是未定义的行为。要打印未签名的值,必须使用%u
或%x
但是您的反转是错误的。您在添加最后一位后移动了结果,而最后一位应该是相反的。您还错过了无符号整数中的位计数(减1)。以下操作应该有效:
#include <stdio.h>
#include <stdlib.h>
unsigned int reverse_bits(unsigned int num) {
unsigned int reverse_num = 0; /* initialize the result*/
unsigned int count = sizeof(unsigned int) * 8; /* counter to track the number of bits in the integer*/
while (num != 0) {
unsigned int last_bit = num & 1; /* get the right-most bit*/
reverse_num <<= 1; /* add one place for the next bit */
reverse_num |= last_bit; /* add that bit to the right-most bit of the desired reversed bits*/
num >>= 1; /* remove one bit from the original */
count--;
}
reverse_num <<= count; /* If the original bits have only 0 s then shift the remaining bits left*/
return reverse_num;
}
int main() {
printf("%08x\n",reverse_bits(1));
printf("%08x\n",reverse_bits(3));
printf("%08x\n",reverse_bits(0x0F0FFFFF));
}
这两者之间有区别。另外,如果您使用打印结果,您希望使用%d
表示整数,使用%u
表示无符号整数。您是如何看到您提到的-2147483648
的?如果您使用的是无符号int
,则不应看到任何负数,除非您混合使用int
andunsigned int
错误,我在您的代码中看不到它。您如何得出结果为-2147483648?您的代码所做的只是调用reverse_bits
函数。生成输出的代码在哪里?您的结论基于该代码?“它显然没有反转整数1的位”如果你不喜欢你得到的东西,你应该告诉我们你期望得到什么以及为什么。魔法常数8
从哪里来?你是说CHAR\u BIT
?1.通过混合int
和unsigned int
,你的意思是当我应该使用int
时我正在使用unsigned int
在用printf(“%u\n”,reverse\u bits(1));
替换reverse\u bits(1);
后,我收到2147483648进程返回11(0xB)
因此,负号变为正号,但它表示进程返回了11,这让我觉得很奇怪。3.我有没有办法要求机器打印出10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,反向位(1));1.您应该使用无符号int
。我指的是您获得输出的方式。在我建议添加printf()之前,您是如何获得输出的?2.这可能是因为您的main()
函数不返回任何内容。将返回0;
添加到main的末尾。是的,1
的位反转应该返回2^31=2147483648
。3.编写一个从十进制转换为二进制的函数。这很简单。如果在Win32/Win64下开发,MS提供了一个非标准函数itoa()
这可以为您做到这一点,但我建议您不要使用它。如果输入值为0,则您会颠倒\u num@PaulHankin的错误,6.5.7 E1的结果您必须阅读到标准的末尾,直到J.2,并查看未定义行为的列表。其中一项是:“表达式移位负数或移位量大于或等于提升表达式的宽度(6.5.7)”。此处,sizeof(unsigned int)*8
是提升表达式的宽度(假设为8位字节),所以移位是未定义的行为。@PaulHankin是对的。对于0
的情况,您依赖于未定义的行为。因为这需要一个等于int
位宽的左移位,这是未定义的行为,但是对于0
您可以不做任何事情就返回。这段新代码不是太多了吗?我很抱歉如果(num==0)返回0,则只需说;函数顶部的更好。
if (count!=sizeof(reverse_num)) {
reverse_num <<= count; /* If the original bits have only 0 s then shift the remaining bits left*/
} else {
reverse_num = 0;
}
return reverse_num;