簡體   English   中英

C - 如何返回所有偶數位設置為 1 且所有奇數位設置為 0 的字?

[英]C - How do I return a word with all even bits set to 1 and all odd bits set to 0?

我只能使用這些運算符! ~ & ^ | + << >>

這是我到目前為止的代碼,但我不知道如何讓它工作

int setEvenBitsToOne(){ int byte = 0x55; int word = byte | byte << 8; return word | word << 16; }

由於整數的大小是已知的,您可以對其進行硬編碼。

int alternatingBits() {
    switch( sizeof(int) ) {
        case 2:
            return 0x5555;
        case 4:
            return 0x55555555;
        case 8:
            return 0x5555555555555555;
        default:
            fprintf(stderr, "Unknown int size: %zu\n", sizeof(int));
            exit(1);
    }
}

sizeof(int)是一個常量,因此編譯器會將所有這些優化為一個常量。

但我假設這是一個有點玩弄的練習。 首先我們需要的是只改變偶數位。 這可以通過將位掩碼設置為 1,將其添加到數字中,將掩碼移動 2 個位置,然后再次添加來完成。

// C doesn't have a way to represent literal binary numbers,
// so I'm using the Perl convention.
num += 0b000001
num += 0b000100
num += 0b010000
...and so on...

位掩碼使用mask = mask << 2

我們還需要知道什么時候停止。 由於我們正在mask < INT_MAX整數大小的限制,我們不想做任何類似mask < INT_MAX因為mask = mask << 2可能會溢出。 相反,我們可以一次遍歷整數 2 中的位數。

int alternatingBits() {
    /* Our number to start with */
    int num = 0;

    /* Our bitmask to add to the number */
    int mask = 1;

    /* The number of bits in an integer
       (to avoid clutering the for loop) */
    const int bits = sizeof(int) * 8;

    /* Step through each even bit */
    for( int i = 0; i < bits; i+=2 ) {
        /* Add the mask */
        num += mask;

        /* Shift the 1 over two bits */
        mask = mask << 2;
    }

    return num;
}

在這種情況下,@Olaf 在評論中提到了一個微妙的問題。 當我們到達終點時, mask將比整數可以容納的多一位。 即使我們在那個時候不使用它,它也會戳破未定義行為的龍,這是編譯器做任何它想做的事情的許可。

我們需要確保不會發生這種情況,這意味着我們必須編寫自己修改過的for循環。

此外,整數的高位用於有符號性,因此為了安全起見,我們可能應該將位掩碼設為無符號整數。

int alternatingBits() {
    int num = 0;
    unsigned int mask = 1;
    const int bits = sizeof(int) * 8;

    /* This does the same as a for loop, but lets us end before incrementing mask */
    int i = 0;
    while( 1 ) {
        num += mask;

        /* increment i and check if we're done before incrementing the mask */
        i += 2;
        if( i >= bits ) {
            break;
        }

        mask = mask << 2;
    }

    return num;
}

現在mask不會溢出,它也不必擔心有符號位。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM