首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >手工计算对数

手工计算对数
EN

Stack Overflow用户
提问于 2018-05-14 17:01:03
回答 2查看 391关注 0票数 1

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

..。哪里

代表logarithmBase

代表价值。

一些示例(参见日志计算器):

代码语言:javascript
复制
The base 2 logarithm of 10 is 3.3219280949

The base 5 logarithm of 15 is 1.6826061945

...

我不想使用像Math.ceil, Math.log, Math.abs, ...这样已经实现的函数调用,因为我想要一个干净的本地解决方案,只处理+-*/和一些循环。

这是我到目前为止得到的代码:

代码语言:javascript
复制
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的正确方法--因此,任何帮助如何修复这段代码都将是非常感谢的。

谢天谢地,乔纳斯。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-14 17:17:04

您可以使用递归方法:

代码语言:javascript
复制
 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);

可用于:

代码语言:javascript
复制
log(2, 4) // 2
log(2, 10) // 3.32196044921875

您可以通过更改depth来影响精度,还可以使用curr更改接受值的范围(当前~180)。

它的工作原理:

如果我们已经达到了想要的深度,或者我们已经找到了一个准确的值:

代码语言:javascript
复制
 depth  <= 0 || base ** curr === n 

然后它只返回curr并完成。否则,它将检查我们要查找的对数是否低于或高于当前的对数:

代码语言:javascript
复制
         base ** curr > n

然后,它将继续递归地搜索一个值,方法是: 1)将depth降低1,2)按当前精度增加/减少curr,3)降低精度

如果您讨厌函数式编程,下面是一个命令式版本:

代码语言:javascript
复制
  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;
  }

顺便说一句,我使用的算法称为“对数搜索”,俗称为“二进制搜索”。

票数 0
EN

Stack Overflow用户

发布于 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

代码语言:javascript
复制
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允许快捷方式,这就是我使用它的原因。当然,平方根应该是表格的。

第二种方法:用泰勒级数.

在规范化步骤之后,您可以使用标准系列。

代码语言:javascript
复制
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和

代码语言:javascript
复制
2 x (0.2558 + 0.2558³/3 + 0.2558^5/5) = 0.5232

lg 27 ~ 4 + 0.5232 / ln 2 = 4.7548
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50335506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档