R..*_*R.. 6 c optimization integer bit-manipulation logarithm
我有32-8191的整数值,我想映射到一个粗略的对数刻度.如果我使用base 2,我可以计算前导零位并将它们映射到8个插槽,但这也是过程粗糙的; 我需要32个插槽(更多会更好,但我需要它们映射到32位值中的位),这对于对数大约为1.18-1.20.任何人都有一些技巧来计算这个值,或者一个合理的近似值,非常快?
我的直觉是用条件将范围分解为2或3个子范围,并为每个使用一个小的查找表,但我想知道是否有一些技巧我可以用count-leading-zeros然后改进结果,特别是因为结果不必是准确的,只是大致对数.
为什么不使用除前导位之外的接下来的两位呢?您可以首先将数字划分为 8 个 bin,然后使用接下来的两位将每个 bin 进一步划分为 4 个。在这种情况下,您可以使用非常快的简单移位操作。
编辑:如果您认为使用对数是一个可行的解决方案。这是一般算法:
令a为对数的底,范围为(b_min, b_max) = (32,8191)。您可以使用以下公式找到底数:
log(b_max/b_min) / log(a) = 32 bin
Run Code Online (Sandbox Code Playgroud)
这给你a~1.1892026。如果使用此 a 作为对数的底,则可以将范围映射(b_min, b_max)到(log_a(b_min), log_a(b_max)) = (20.0004,52.0004)。
现在只需要将 all 元素减去 a20.0004即可得到 range (0,32)。它保证所有元素都是对数均匀的。完毕
注意:任一元素可能由于数值错误而超出范围。您应该自己计算出准确的值。
注2:log_a(b) = log(b)/log(a)