【发布时间】:2023-01-10 12:04:19
【问题描述】:
计算以 2 为底的整数对数在几乎任何计算机语言中都非常容易 - 您只需找到二进制表示中最大的“1”,其余的变为零。
是否可以对其他基数执行相同的快速技巧,例如 3,- 计算基数 3 的对数或从下面获取最接近的整数是正确的 3n?
【问题讨论】:
标签: bit-manipulation logarithm integer-arithmetic
计算以 2 为底的整数对数在几乎任何计算机语言中都非常容易 - 您只需找到二进制表示中最大的“1”,其余的变为零。
是否可以对其他基数执行相同的快速技巧,例如 3,- 计算基数 3 的对数或从下面获取最接近的整数是正确的 3n?
【问题讨论】:
标签: bit-manipulation logarithm integer-arithmetic
是的,使用与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") }
【讨论】: