我想以二進制格式獲取等于 1 的索引,現在我使用這樣的代碼:
inline static uint8_t the_index(uint32_t val){
return uint8_t(log(val & ((~val) 1))/log(2));
}
我想知道是否有其他方法可以實作相同的目標?有沒有可能使用位操作來解決這個問題?
我這樣做是為了迭代一個值并構建一些依賴于迭代位置的操作,像這樣的偽代碼:
while (temp) {
auto cur_index = the_index(temp);
auto window = ((1 << i) - 1) << cur_index;
if (((temp & window) ^ window) == 0) {
//....do something
}
temp &= temp - 1;
}
uj5u.com熱心網友回復:
有一個標準功能:
auto cur_index = std::countr_zero(temp);
在我的系統上,這編譯為:
xor eax, eax
tzcnt eax, edi
請注意,無論輸入是否恰好有一個設定位,此函式都會成功地從右計數零位直到第一個位。
uj5u.com熱心網友回復:
如果問題是關于找到值中單個位的索引,例如uint32_t x = b000010000;,一個快速的方法是
auto index = builtin_popcount(x - 1);
// example: b000010000 - 1
// b000001111
// popcount(b000001111) == 4
在 arm64 架構中,最好的方法是使用 count_leading_zero(x) 指令/操作,因為通用暫存器缺乏快速 popcount。
更仔細地閱讀 OP,不能保證x只設定一位——問題似乎是找到最低有效位設定的索引。這可以與
x = temp & (0-temp);
uj5u.com熱心網友回復:
我建議您使用__builtin_ctzl:回傳 x 中從最低有效位位置開始的尾隨 0 位的數量。(警告:如果 x 為 0,則結??果未定義)。
示例:__builtin_ctzl(0x10) = 4, __builtin_ctzl(0x20) = 5
對于您的情況,您可以像這樣使用它:
unsigned index;
do {
index = temp ? __builtin_ctzl(temp) : 0;
... //do your stuff
temp -= pow(2, index);
} while (index);
uj5u.com熱心網友回復:
也許像這樣?
std::vector<uint8_t> the_index(uint32_t val){
std::vector<uint8_t> out;
uint8_t index = 0;
uint32_t x = 1;
for (int i = 0; i < 32; i) {
if (val & x) out.push_back(index);
x <<= 1;
index ;
}
return out;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/369663.html
上一篇:QtC 中奇怪的執行順序
