问题的根源在于,易受浮点截断错误影响的 log 函数被用于解决自然数领域的问题。首先,我应该指出,实际上,在给出的示例中,1 确实是正确答案。我们正在寻找最大的 x 使得 p^x < n; 不是 p^x <= n。2^1 < 4,但 2^2 不是。话虽如此,我们仍然有一个问题,因为当 p^x = n 对于某些 x 时,log(n) 除以 log(p) 可能会略高于整数而不是低于整数,除非有一些系统性在实现日志功能时存在偏差。所以在这种情况下,有一些 x 为 p^x=n,我们实际上希望确保向下舍入到下一个较低的 x 整数值。
所以即使是这样的解决方案也不能解决这个问题:
display truncate(round(log(4) / log(2), 10) , 0) .
我看到两种方法来处理这个问题。一个类似于您已经尝试过的,除了因为我们实际上想要向下舍入到下一个较低的自然数,我们将减去而不是添加:
display truncate(log(4) / log(2) - 0.00000001, 0) .
只要 n 小于 10^16,这将起作用,但更简洁的解决方案是使用实际整数数学来解决边界条件。当然,如果你得到的数字高于最大整数值,这也会失败。但如果这不是问题,您可以使用您的第一个解决方案获得近似解决方案:
display truncate(log(4) / log(2) , 0) .
然后测试结果是否适用于方程 p^x < n。如果不小于 n,则减一并重试。
顺便说一句,自然数的定义不包括零,所以如果 x 的最低可能值为 1,那么 p^x 的最低可能值为 p,所以如果 n 小于或等于到 p,没有自然数解。