【发布时间】:2019-03-09 06:22:27
【问题描述】:
有人知道上/下转换位数组的算法吗?
即:分辨率为1/16时:
每 1 位 = 16 位。 (低分辨率到高分辨率)
1010 -> 1111111111111111000000000000000011111111111111110000000000000000
反过来,16位=1位(高分辨率到低分辨率)
1111111111111111000000000000000011111111111111110000000000000000 -> 1010
现在我正在一点一点地循环,效率不高。使用整个 64 位字会更好,但是当字不能被分辨率均等整除时会遇到问题(某些位可能会溢出到下一个字)。
C++:
std::vector<uint64_t> bitset;
C:
uint64_t *bitset = calloc(total_bits >> 6, sizeof(uint64_t)); // free() when done
通过以下方式访问:
const uint64_t idx = bit >> 6;
const uint64_t pos = bit % 64;
const bool value = (bitset[idx] >> pos) & 1U;
并设置/清除:
bitset[idx] |= (1UL << pos);
bitset[idx] &= ~(1UL << pos);
两个相同分辨率的位集的 OR(或 AND/XOR/AND/NOT)是使用完整的 64 位字完成的:
bitset[idx] |= source.bitset[idx];
我正在处理足够大的位集(2+ 十亿位),我正在寻找循环中的任何效率。我发现优化循环的一种方法是使用__builtin_popcountll 检查每个单词,然后在循环中向前跳过:
for (uint64_t bit = 0; bit < total_bits; bit++)
{
const uint64_t idx = bit >> 6;
const uint64_t pos = bit % 64;
const uint64_t bits = __builtin_popcountll(bitset[idx]);
if (!bits)
{
i += 63;
continue;
}
// process
}
我在寻找算法/技术而不是代码示例。但如果你有代码要分享,我不会拒绝。任何学术研究论文也将不胜感激。
提前致谢!
【问题讨论】:
-
std::vector<uint64_t> bitset;不在 C 中,你不是。在标记额外语言时要小心并确保每种语言都是相关的。如果您真的不在乎使用什么语言,请标记为language-agnostic。 -
感谢@user4581301 的评论。您可以将
std::vector<uint64_t> bitset替换为uint64_t *bitset,它将在C 中工作。 -
将 N 位信号转换为 M 位,其中 N != M 并尽量减少噪声的引入,这实际上是一个巨大的话题。处理这个问题的一大类研究是 Delta-Sigma(也称为 Sigma-Delta)调制。 en.wikipedia.org/wiki/Delta-sigma_modulation
-
这太棒了,感谢@gene 为这个问题命名!我现在会再用谷歌搜索一下:)