找到64位数的位置

Fox*_*x-3 26 c

我试图在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)

更改11ull意味着左移位是在类型的值unsigned long long而不是int,因此位掩码实际上可以到达位置32到63.删除比较为1是因为number & mask(其中mask只有一个位设置)的结果是mask0,mask当i为0时,仅等于1.

但是,当我做出改变时,我的输出是0 59,这仍然不是你所期望的.剩下的问题是576460752303423489(十进制)= 0800 0000 0000 0001(十六进制). 0 59是该数字的正确输出.您想要的号码是9223372036854775809(十进制)= 8000 0000 0000 0001(十六进制).

顺便说一句,main需要返回int,而不是void,并且需要显式return 0;作为其最后一个操作(除非您使用返回代码执行更复杂的操作).是的,C99让你省略.无论如何要这样做.

  • 我只是把这个号码插入Wolfram Alpha作为一个完整性检查; `0 59`*是*正确的答案. (3认同)

dav*_*mac 6

因为您正在编译和运行的平台上(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.