我试图在64位数字中找到两个1的位置.在这种情况下,那些位于第0和第63位置.这里的代码返回0和32,这只是对齐的一半.为什么这不起作用?
#include<stdio.h>
void main()
{
unsigned long long number=576460752303423489;
int i;
for (i=0; i<64; i++)
{
if ((number & (1 << i))==1)
{
printf("%d ",i);
}
}
}
Run Code Online (Sandbox Code Playgroud)
zwo*_*wol 24
线路上有两个漏洞
if ((number & (1 << i))==1)
Run Code Online (Sandbox Code Playgroud)
哪个应该读
if (number & (1ull << i))
Run Code Online (Sandbox Code Playgroud)
更改1为1ull意味着左移位是在类型的值unsigned long long而不是int,因此位掩码实际上可以到达位置32到63.删除比较为1是因为number & mask(其中mask只有一个位设置)的结果是mask或0,mask当i为0时,仅等于1.
但是,当我做出改变时,我的输出是0 59,这仍然不是你所期望的.剩下的问题是576460752303423489(十进制)= 0800 0000 0000 0001(十六进制). 0 59是该数字的正确输出.您想要的号码是9223372036854775809(十进制)= 8000 0000 0000 0001(十六进制).
顺便说一句,main需要返回int,而不是void,并且需要显式return 0;作为其最后一个操作(除非您使用返回代码执行更复杂的操作).是的,C99让你省略.无论如何要这样做.
因为您正在编译和运行的平台上(1 << i)是32位int值.然后,对于&具有该number值的操作,这被符号扩展到64位,导致位31被复制到位32到63中.
此外,您正在将结果&与1 进行比较,这是不正确的.如果该位置位则不为0,但不会为1.
将32位int移位32是未定义的.
此外,您的输入数字不正确.设置的位位于0和59位(如果您希望从1开始计数,则为1和60).
修复是使用(1ull << i),或以其他方式右移原始值并将&其与1(而不是左移1).当然,如果你做左移1和&它的原始值,结果将不是1(除了位0),所以你需要比较!= 0而不是== 1.