有人可以向我解釋一下這種算法在32位系統上如何將MSB轉換爲LSB或LSB爲MSB?C MSB到LSB解釋
unsigned char b = x;
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
我看過十六進制值以LU結尾,或者只是U代碼之前,它們是什麼意思?
謝謝!
有人可以向我解釋一下這種算法在32位系統上如何將MSB轉換爲LSB或LSB爲MSB?C MSB到LSB解釋
unsigned char b = x;
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
我看過十六進制值以LU結尾,或者只是U代碼之前,它們是什麼意思?
謝謝!
假定char
有8位,所以unsigned char b = x
取x的低8位。
帶有0x22110的掩碼提取第4,8,13和17位(從最低有效位的0開始編號)。所以,乘以0x0802,我們只關心它在這些位上的位置。在0x802中,第1位和第11位開啓,因此該乘法將第1位到第8位中的b
的八位副本與第11位至第18位中的另一副本相複製。沒有重疊,因此不會添加位在更一般的乘法中重疊。
從這個產品,我們把這些位:
b
3。 (從位1開始複製的位4,所以位4-1 = 3的b
)。b
的位7。 (8-1 = 7)b
的位2。 (13-11 = 2.)b
的第6位。 (17-11 = 6)類似地,掩模通過0x88440提取比特6,10,15,和19。乘以0x8020地方b
以比特5至12的副本,並在比特另一個副本從這個產品,我們採取這些位:
b
的位1。b
的第5位。b
。b
的第4位。然後我們OR那些一起,產生:
b
位3。b
的位1。b
的第7位。b
的第5位。b
的位2。b
。b
的第6位。b
的第4位。致電此結果t
。
我們將乘以0x10101,右移16,並分配給b
。該分配轉換爲unsigned char
,因此只保留低8位。移位後的低8位是位移前的24位至31位。所以我們只關心產品中的24位到31位。
乘法器0x10101的位爲0,8和16組。因此,結果中的位24是t
中的位24,16和8的和,加上來自別處的任何進位。但是,沒有進位:請注意,t
中的任何設置位都不相等,因爲乘法器中的位是。因此,他們中的任何一個都不能直接貢獻於產品中的相同位。產品中的每一位都是t
中最多一位的結果。我們只需要弄清楚哪個位是。
位24必須來自位於t
的位8,16或24。只有第8位可以設置,它是從b
的第7位。推斷所有的位是這樣的:
t
,這是位7 b
。t
的位17,位於b
的位6。t
的位10,位於b
的位5。t
的位19,位於b
的位4。t
的位4,位於b
的位3。t
的位13,位於b
的位2。t
的位6,位於b
的位1。t
的位15,位於b
的位0。因此,位24至31中的產品是比特7到0在b
,所以最後產生的八位是位7到0的b
。
+1非常好的徹底解釋 –
感謝您的解釋,非常有幫助。花了幾輪看你的解釋,並通過一個例子,但我想我現在明白了。 – txcotrader
要回答你的第二個問題,u
表示將十六進制常量作爲無符號(如果需要將其擴展爲更長的寬度),並且l
意味着將其視爲long
。
我正在處理您的第一個問題。
當你將它看作乘法和十六進制時,很難想象這個算法正在做什麼。當您將其轉換爲二進制數並用相當數量的移位操作替換乘法時,它變得更加清晰。本質上,它所做的是通過移位和掩蓋部分字節來擴展字節的部分內容,然後實現一個並行的半加器來重建零件,這恰好與它們開始的位置相反。
例如,對於b
b * 0x0802 = b << 11 | b << 1
插件在某些值(二進制),並按照沿。
查看b爲8位值abcdefgh
其中每個字母爲單個位(0或1),其中a
爲最高位,h
爲最低位。然後看看每個操作做那些位:
b * 0x0802LU = 00000abcdefgh00abcdefgh0
b * 0x0802LU & 0x22110LU = 000000b000f0000a000e0000
b * 0x8020LU = 0abcdefgh00abcdefgh00000
b * 0x8020LU & 0x88440LU = 0000d000h0000c000g000000
((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU))
= 0000d0b0h0f00c0a0g0e0000
所以在這一點上,它打亂了位,並蔓延出來。
(....) * 0x10101LU = d0b0h0f00c0a0g0e0000
+ d0b0h0f00c0a0g0e000000000000
+ d0b0h0f00c0a0g0e00000000000000000000
= d0b0f0f0dcbahgfedcbahgfe0c0a0g0e0000
(...) * 0x10101LU >> 16 = d0b0f0f0dcbahgfedcba
b = hgfedcba
乘法相當於shift/add/add(常量中設置了3位),它將它們應該結束的位排成一行。然後最後的移位和減少到8位給你最後的位反轉結果。
'u' =無符號整數,'lu' = long無符號整數... – Mysticial
不是一個真正的解釋,但我認爲理解最好的方法是通過二進制的一些例子,嘗試x = 1000-0000- 0000-0000和x = 0000-0000-0000-00001 –