我想手工计算mathematical logarithm"" ...
...其中代表 logarithmBase ,代表值。
一些例子(参见Log calculator):
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 的正确方法 - 所以任何有关如何修复此代码的帮助都会非常感激。
感谢一百万提前的乔纳斯。
答案 0 :(得分:0)
第一种方法:使用常量表。
首先将参数标准化为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
with open('result.csv','w',newline='') as f:
w = csv.writer(f)
w.writerow(['NAME','ADDRES','MOBILE','EMAIL']) # write header once
entries = soup.find_all('div', class_='deleadres')
for entry in entries: # loop over all `.deleadres` elements
dname = entry.find('div', class_="delrname").text
dadres = entry.find('p').text
dmobile = entry.find('div', class_="clearfix").text
demail = entry.find('div', class_="mobno").text
w.writerow([dname,dadres,dmobile,demail]) # write data rows for each entry
真正的价值是4.7549。
请注意,您可以与其他基地合作,尤其是e。在某些情况下,base 2允许快捷方式,这就是我使用它的原因。当然,平方根应该制成表格。
第二种方法:使用泰勒系列。
在标准化步骤之后,您可以使用标准系列
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
...
收敛于log(1 + x) = x - x²/2 + x³/3 - ...
。 (注意:我们现在有自然对数。)
由于收敛对于接近1的值来说太慢,建议使用上述方法将范围缩小到[1,√2]。然后每个新术语都会带来一点新的准确性。
或者,您可以将该系列用于log((1 + x)/(1 - x)),即使对于参数2,也可以提供良好的收敛速度。请参阅https://fr.wikipedia.org/wiki/Logarithme_naturel#D%C3%A9veloppement_en_s%C3%A9rie
示例:x = 1.6875,y = 0.2558和
|x| < 1
答案 1 :(得分:-1)
您可以使用递归方法:
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
降低一个
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;
}
顺便说一句,我使用的算法称为"logarithmic search",通常称为“二分搜索”。