有办法在BigInt中求出JavaScript的对数吗?
对于正常数字,您可以使用以下代码:
const largeNumber = 1000;
const result = Math.log(largeNumber);但是,我需要处理阶乘数字,可能大于170!,这样常规的数字类型就不能工作了。Math.log不适用于BigInt。那么我怎么得到对数呢?
const largeNumber = BigInt(1000);
const result = ???发布于 2021-12-16 19:50:09
如果您不想返回一个BigInt,那么下面的内容可能也适用于您:
function log10(bigint) {
if (bigint < 0) return NaN;
const s = bigint.toString(10);
return s.length + Math.log10("0." + s.substring(0, 15))
}
function log(bigint) {
return log10(bigint) * Math.log(10);
}
function natlog(bigint) {
if (bigint < 0) return NaN;
const s = bigint.toString(16);
const s15 = s.substring(0, 15);
return Math.log(16) * (s.length - s15.length) + Math.log("0x" + s15);
}
const largeNumber = BigInt('9039845039485903949384755723427863486200719925474009384509283489374539477777093824750398247503894750384750238947502389475029384755555555555555555555555555555555555555554444444444444444444444444222222222222222222222255666666666666938475938475938475938408932475023847502384750923847502389475023987450238947509238475092384750923847502389457028394750293847509384570238497575938475938475938475938475555555555559843991');
console.log(natlog(largeNumber)); // 948.5641152531601
console.log(log10(largeNumber), log(largeNumber), log(-1))
// 411.95616098588766
// 948.5641152531603
// NaN
log10()将返回作为参数输入的任何BigInt或Int数字的标准精度浮动。
正如@Mielipuoli非常正确地提到的,自然对数可以计算为
function log(bigint) {
return log10(bigint) / Math.log10(Math.E);
}或者,更简单,如我上面的片段所示,如log10(bigint) * Math.log(10)。
@Nat已经在下面的注释中解释了这种方法是如何工作的,即通过分别计算对数的整数和分数部分并将它们加起来。关于结果的精度:Math.log10()工作在一个浮点数上,通常有13到14位十进制的精度,因此,对于结果来说,这也是您所能期望的。
因此,我将BigInt数字的字符串表示形式截断为15个字符。在隐式类型转换到浮点数时,任何进一步的小数位都会被忽略。
我还在这里添加了十六进制版本,由@PeterCordes建议,并由@ here进一步开发为natlog()。它可以工作--可能比我原来的解决方案更快--并产生“相同”的结果(只有最后显示的数字在两个结果之间偏离)!
发布于 2021-12-17 04:05:26
其他答案充分解决了标题中的问题,即:“我如何计算BigInt的对数?”但是,您还提到您对阶乘的对数特别感兴趣,对于这种对数,不同的算法可以避免范围困难。
应用log(ab) = log(a) + log(b),以下函数计算阶乘的日志:
function logFactorial(n) {
let total = 0;
for (let current = 1; current <= n; ++current) {
total += Math.log10(current);
}
return total;
}
console.log(logFactorial(170));
发布于 2021-12-16 20:41:25
受MWO答案的启发,您可以简单地将BigInt转换为与您想要计算的对数具有相同基数的字符串,并得到字符串长度。
例如,要计算floor(log2(9007199254740991)),可以执行BigInt("9007199254740991").toString(2).length - 1。
注意,toString只允许从2到36之间的碱基。
https://stackoverflow.com/questions/70382306
复制相似问题