我想用手工计算数学对数 .

..。哪里

代表logarithmBase和

代表价值。
一些示例(参见日志计算器):
The base 2 logarithm of 10 is 3.3219280949
The base 5 logarithm of 15 is 1.6826061945
...我不想使用像Math.ceil, Math.log, Math.abs, ...这样已经实现的函数调用,因为我想要一个干净的本地解决方案,只处理+-*/和一些循环。
这是我到目前为止得到的代码:
function myLog(base, x) {
let result = 0;
do {
x /= base;
result ++;
} while (x >= base)
return result;
}
let x = 10,
base = 2;
let result = myLog(base, x)
console.log(result)
但是,上面的方法似乎并不是计算对数到基数N的正确方法--因此,任何帮助如何修复这段代码都将是非常感谢的。
谢天谢地,乔纳斯。
发布于 2018-05-14 17:17:04
您可以使用递归方法:
const log = (base, n, depth = 20, curr = 64, precision = curr / 2) =>
depth <= 0 || base ** curr === n
? curr
: log(base, n, depth - 1, base ** curr > n ? curr - precision : curr + precision, precision / 2);可用于:
log(2, 4) // 2
log(2, 10) // 3.32196044921875您可以通过更改depth来影响精度,还可以使用curr更改接受值的范围(当前~180)。
它的工作原理:
如果我们已经达到了想要的深度,或者我们已经找到了一个准确的值:
depth <= 0 || base ** curr === n 然后它只返回curr并完成。否则,它将检查我们要查找的对数是否低于或高于当前的对数:
base ** curr > n然后,它将继续递归地搜索一个值,方法是: 1)将depth降低1,2)按当前精度增加/减少curr,3)降低精度
如果您讨厌函数式编程,下面是一个命令式版本:
function log(base, n, depth = 20) {
let curr = 64, precision = curr / 2;
while(depth-- > 0 && base ** curr !== n) {
if(base ** curr > n) {
curr -= precision;
} else {
curr += precision;
}
precision /= 2;
}
return curr;
}顺便说一句,我使用的算法称为“对数搜索”,俗称为“二进制搜索”。
发布于 2018-05-15 07:13:46
第一种方法:有一个常数表.
首先,将参数规范化为1到2之间的一个数字(这是通过乘以或除以所需的2倍来实现的--保持对这些操作的计数)。为了提高效率,如果值可以跨越多个数量级,而不是相同的因子,则可以使用平方序列2、4、16、256.,然后在值括号内进行二次搜索。
F.i。如果指数16=2^4工作,但不工作256=2^8,您尝试2^6,然后其中一个2^5和2^7取决于结果。如果最终指数为2^d,则线性搜索采用O(d)运算,而几何/二次搜索仅为O(log d)。为了避免分裂,最好保持一张消极权力表。
正常化之后,您需要细化尾数。将该值与√2进行比较,如果乘以1/√2,则得到1和√2之间的值,然后与√√2进行比较,以此类推。当你走的时候,你把重量加1/2,1/4,.当一个比较返回更大的值时。
最后,指数为基2对数。
例子: lg 27
27 = 2^4 x 1.6875
1.6875 > √2 = 1.4142 ==> 27 = 2^4.5 x 1.1933
1.1933 > √√2 = 1.1892 ==> 27 = 2^4.75 x 1.0034
1.0034 < √√√2 = 1.0905 ==> 27 = 2^4.75 x 1.0034
...真正的价值是4.7549。
请注意,您可以使用其他基础,特别是e。在某些情况下,base 2允许快捷方式,这就是我使用它的原因。当然,平方根应该是表格的。
第二种方法:用泰勒级数.
在规范化步骤之后,您可以使用标准系列。
log(1 + x) = x - x²/2 + x³/3 - ...它收敛于|x| < 1。(注意:我们现在有了自然对数。)
由于收敛速度太慢,数值接近1,建议使用上述方法将范围缩小到[1,√2]。然后每一个新的术语都会带来新的精确性。
或者,您也可以将这个系列用于log((1 +x)/(1-x)),即使对于参数2,它也提供了很好的收敛速度。
示例:使用x= 1.6875,y= 0.2558和
2 x (0.2558 + 0.2558³/3 + 0.2558^5/5) = 0.5232
lg 27 ~ 4 + 0.5232 / ln 2 = 4.7548https://stackoverflow.com/questions/50335506
复制相似问题