翻转位错误

时间:2014-05-13 17:34:20

标签: c bitwise-operators

来电者希望我们回答以下64个问题:

是基本素数?基数+ 1素数?基数+ 2素数?基数+ 3素数? ...是基数+ 63素数?

该函数应该构建并返回一个64位无符号长整型,其中每个位保存相应问题的答案:返回值的#k位告知base + k是否为素数。

不确定我在哪里出错了。该函数应输出0x820A00A08800228AULL,但我得到的是10004514.我想从MSB开始,向左移动会逐渐构建它。

int prime( unsigned long long n ){
    int a;

    for( a = 2; a<=sqrt((double)n); a++ ){
        if( n%a == 0 )
            return 0;
    }
    if( a == n )
        return 1;
}

unsigned long long setPrimeBits( unsigned long long base ){
    int a;
    unsigned long long b = 0x000000000000000ULL;

    for( a=63; a>=0; a-- ){
        if( prime( base+a ) ){
            b |= 1;
            b = b<<1;
        }//end if
        else b = b<<1;
    }//end for
    return b;
}

Main&amp;输出如下......

int main(){
    printf( "%16X\n", setPrimeBits( 100 ));
}
        10004514

1 个答案:

答案 0 :(得分:3)

  1. 您的prime()函数表现出未定义的行为。如果找不到素数,则最终条件也将为假(因为a靠近sqrt(n),而不是n附近),这意味着您将没有执行返回语句。要解决此问题,只需return 1完成for循环(即找不到素数除数)。

  2. 您想要打印unsigned long long。格式字符串为%016llX

  3. 您将b转移了太多次。让我们假设for循环的最后一个循环(计算a + 0)是素数。你会把它写到底部位,然后将它移到一个地方。

  4. 修复这些错误,我们得到一些看起来像的代码:

    #include <stdio.h>
    #include <math.h>
    
    int prime( unsigned long long n ){
        int a;
    
        for(a = 2; a<=sqrt((double)n); a++)
            if( n%a == 0 )
                return 0;
    
        return 1;
    }
    
    unsigned long long setPrimeBits( unsigned long long base ){
        int a;
        unsigned long long b = 0x000000000000000ULL;
    
        for(a = 63; a >= 0; a--) {
            b = b << 1;
            if(prime(base+a))
                b |= 1;
        }
    
        return b;
    }
    
    int main(){
        printf( "%16llX\n", setPrimeBits( 100 ));
    }
    

    运行时报告:

    [12:54pm][wlynch@watermelon /tmp] ./pr 
    820A00A08800228A
    

    而且,因为似乎对其他答案中的左移有困惑,你可以编写一个如下所示的等效setPrimeBits()

    unsigned long long setPrimeBits( unsigned long long base ){
        int a;
        unsigned long long b = 0x000000000000000ULL;
    
        for(a = 0; a < 64; a++)
            if (prime(base+a))
                b |= (1ULL << a);           
    
        return b;
    }