簡體   English   中英

K&R C編程語言練習2-9

[英]K&R C programming language exercise 2-9

我不明白 K&R C 編程語言第 2 章 2.10 中的練習 2-9:

練習 2-9。 在二進制補碼系統中, x &= (x-1) 刪除 x 中最右邊的 1 位。 解釋為什么。 使用此觀察編寫更快版本的 bitcount 。

bitcount 函數是:

/* bitcount: count 1 bits in x */

int bitcount(unsigned x)
{
    int b;
    for (b = 0; x != 0; x >>= 1)
        if (x & 01)
            b++;
    return b;
}

該函數在檢查它是否為 bit-1 后刪除最右邊的位,然后彈出最后一位。

我不明白為什么x&(x-1)刪除最右邊的 1 位? 例如,假設 x 是1010並且 x-1 是二進制的1001 ,並且x&(x-1)將是1011 ,所以最右邊的位將在那里並且是1,我錯在哪里?

另外,練習中提到了二進制補碼,和這個問題有關系嗎?

非常感謝!!!

首先,您需要相信 K&R 是正確的。 其次,你可能對這些詞有一些誤解。

讓我再為你澄清一下。 最右邊的 1 位不是最右邊的位,而是最右邊的位,二進制形式為 1。

讓我們任意假設 x 是 xxxxxxx1000(x 可以是 0 或 1)。 然后從右到左,第四位是“最右邊的1位”。 在這個理解的基礎上,讓我們繼續這個問題。

為什么 x &=(x-1) 可以刪除最右邊的 1 位?

在二進制補碼系統中,-1 用全 1 位模式表示。

所以x-1其實就是x+(-1),也就是xxxxxxx1000+11111111111。 棘手的問題來了。

在最右邊的 1 位之前,所有 0 變為 1,最右邊的 1 位變為 0,並且有進位 1 轉到左側。 並且這個 1 將繼續向最左邊前進並導致溢出,同時,所有 'x' 位仍然是 a,因為 'x'+'1'+'1'(carry) 導致一個 'x' 位。

然后 x & (x-1) 將刪除最右邊的 1 位。

希望你現在能明白。

謝謝。

這里有一個簡單的方法來解釋它。 讓我們任意假設數字 Y 是 xxxxxxx1000(x 可以是 0 或 1)。

xxxxxxx1000 - 1 = xxxxxxx0111

xxxxxxx1000 & xxxxxxx0111 = xxxxxxx0000(看,“最右邊的 1”不見了。)

所以在 Y 變為 0 之前Y &= (Y-1) 的重復次數將是Y中 1 的總數。

為什么x & (x-1)刪除最右邊的順序位? 試試看:

如果最右邊的位是 1,則 x 有 a a...b1的二進制表示, x-1a...b0所以按位和將給出a...b1因為and和和保持公共位不變1 & 00

否則 x 具有 a a...b10...0的二進制表示; x-1a...b01...1並且出於與上述相同的原因, x & (x-1)將是a...b00...0再次清除最右邊的順序位。

因此,不是掃描所有位以找出哪些是 0 哪些是 1,您只需迭代操作x = x & (x-1)直到 x 為 0:步數將是 1 位的數量。 它比簡單的實現更有效,因為從統計上講,您將使用一半的步驟。

代碼示例:

int bitcount(unsigned int x) {
    int nb = 0;
    while (x != 0) {
        x &= x-1;
        nb++
    }
    return nb;
}

我已經很晚了(≈ 3.5yrs)但是你的例子有錯誤。

x = 1010 = 10
x - 1 = 1001 = 9
1010 & 1001 = 1000

如您所見,它刪除了 10 中最右邊的位。

7 = 111
6 = 110
5 = 101
4 = 100
3 = 011
2 = 010
1 = 001
0 = 000

觀察任何數字中最右邊的 1 的位置,該數字減去 1 的相同位置的位為 0。因此,將 x 與 x-1 進行 AND 運算將重置(即設置為 0)最右邊的位。

7 & 6 = 111 & 110 = 110 = 6
6 & 5 = 110 & 101 = 100 = 4
5 & 4 = 101 & 100 = 100 = 4
4 & 3 = 010 & 011 = 010 = 2
3 & 2 = 011 & 010 = 010 = 2
2 & 1 = 010 & 001 = 000 = 0
1 & 0 = 001 & 000 = 000 = 0

暫無
暫無

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

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