【问题标题】:How to calculate integer logarithm of base 3, using fast bit operations?如何使用快速位运算计算以 3 为底的整数对数?
【发布时间】:2023-01-10 12:04:19
【问题描述】:

计算以 2 为底的整数对数在几乎任何计算机语言中都非常容易 - 您只需找到二进制表示中最大的“1”,其余的变为零。

是否可以对其他基数执行相同的快速技巧,例如 3,- 计算基数 3 的对数或从下面获取最接近的整数是正确的 3n

【问题讨论】:

    标签: bit-manipulation logarithm integer-arithmetic


    【解决方案1】:

    是的,使用与Find integer log base 10 of an integer相同的方法,我们可以达到同样的效果。我们只需要用 3 的幂替换 10 的幂,log102 带日志3个2,和乘法1个日志3个2个≈ ³²³⁄₅₁₂ 被使用

    这是一个用 JavaScript 编写的简单 PoC,您可以在浏览器中实时试用。查看函数ilog3()

    const POW3 = new Int32Array([ 1, 3, 9, 27, 81, 243, 729,
      2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969,
      14348907, 43046721, 129140163, 387420489, 1162261467 ])
    
    function ilog2(x) {
      // Here floating-point log is used because JavaScript doesn't have
      // find-first-set/count-leading-zero/integer-log-2/whatever
      // to get the position of the most significant bit. 
      // On platforms/languages with that feature we should use that instead
      return Math.trunc(Math.log2(x))
    }
    
    function ilog3(x) {
      let t = (ilog2(x) + 1)*323 >>> 9
      return t - (x < POW3[t])
    }
    
    allOK = true
    const Log3 = Math.log(3)
    function check(x) {
      a = ilog3(x);
      b = Math.trunc(Math.log(x)/Log3);
      if (a != b) {
        console.log([x, a, b])
        allOK = false
      }
    }
    
    function checkAll(x) {
      if (x > 1) { check(x - 1) }
      check(x)
      check(x + 1)
    }
    
    // Check if log3(x - 1), log3(x), log3(x + 1) are correct
    // for all x that are powers of 3
    POW3.forEach(checkAll)
    if (allOK) { console.log("OK") }

    【讨论】:

      猜你喜欢
      • 2020-12-08
      • 2012-07-07
      • 1970-01-01
      • 2018-10-24
      • 2016-02-21
      • 2011-03-19
      • 2016-01-26
      • 2011-08-31
      相关资源
      最近更新 更多