手工计算对数的方法和对应的C代码

Posted dog250

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手工计算对数的方法和对应的C代码相关的知识,希望对你有一定的参考价值。

如何手算对数?为简单起见,以 2 2 2为底数演示。

问题:求 log ⁡ 2 a \\log_2a log2a的值,其中 a a a为已知实数。

由于人们的思维逻辑普遍是线性的,而对数是非线性的,对数需要规模化思维才更好理解,因此将问题转化成求指数会更直观一些:

2 x = a 2^x=a 2x=a,问 a a a可以拆成多少 2 2 2的次幂相乘,将幂加起来即可。

下面是过程:

a a a不断除以2,一直到除不尽余 b b b

2 x = a = 2 1 2 1 2 1 2 1 b 2^x=a=2^12^12^12^1b 2x=a=21212121b

b b b 2 2 2小,它如何写成 2 2 2的次幂呢?

由于指数函数 f ( x ) = 2 x f(x)=2^x f(x)=2x递增步长是 2 2 2的次幂, b b b 2 2 2 α \\alpha α次幂,等价于 b 2 b^2 b2 2 2 2 α 2 \\dfrac{\\alpha}{2} 2α次幂,这样如果 b 2 b^2 b2大于 2 2 2,就可以递归了。

显然 b = ( b 2 ) 1 2 b=(b^2)^{\\frac{1}{2}} b=(b2)21,设 b 2 = c b^2=c b2=c,则类似 a a a拆分 c c c

c = 2 1 2 1 d c=2^12^1d c=2121d

显然 d = ( d 2 ) 1 2 d=(d^2)^{\\frac{1}{2}} d=(d2)21,设 d 2 = e d^2=e d2=e,则类似 a a a拆分 e e e

这是一个递归的手算对数的最简单方法,不用查表,不需要任何高数知识。

若底数不是 2 2 2,假设是 A A A,则:

A x = A 1 A 1 . . b A^x=A^1A^1..b Ax=A1A1..b

b = ( b A ) 1 A b=(b^A)^{\\frac{1}{A}} b=(bA)A1

接着递归处理 b A b^A bA即可。

下面是一个按照上述的手算步骤写的C代码,可求任意底数的对数:

#include <stdio.h>
#include <stdlib.h>

double logarithm(int i, double temp, double base, double num, int acc)
{
        if (acc == 1)
                return 0;
        if (num >= base) {
                return 1 + logarithm(0, 1, base, num/base, acc-1);
        } else {
                while (i++ < base)  {
                        temp *= num;
                }
                return (1/base)*logarithm(0, 1, base, temp, acc-1);
        }
}

int main(int argc, char **argv)
{
        double base, num, ret;
        int acc = (int)atoi(argv[1]); // 递归层数,表示精度,一般设置100

        base = (double)atoi(argv[2]); // 底数
        num = (double)atoi(argv[3]); // 待求数
        ret = logarithm(0, 1, base, num, acc);
        printf("%.18lf\\n", ret);

}

这篇文章源自于一个朋友在知乎上的问题:
怎么推导或证明 e^x 的导数是自身? - 知乎
我以为:
y = e x y=e^x y=ex表示在以 x x x为增长率的增长极限(比如以 x x x为利率的复利极限),那么在 x x x为增长率的时候, y y y的增长最大就是 e x e^x ex,这就是 y y y的导数(毕竟导数就是增长率的极限)了,就是它自身了。
e e e是通过 ( 1 + 1 n ) n (1+\\dfrac{1}{n})^n (1+n1)n的极限定义出来的,所以直接从那个定义的形式入手去理解即可。”
说实话,将 e e e的定义用二项式展开,然后求极限后求导会更像个正经答案,但那只是数学把式,我承认摆置数学把式是笛卡尔方法论的核心用例(在笛卡尔之前,数学无法工程化),这也是我一再强调和推崇的,但同时我需要有一个直观的解释,而不是单纯比划公式。读历史会发现,任何伟大的公式背后,在一开始都源自于一种直观的直觉,然后在寻求表达时才有了公式,比如伟大的平方反比律。
一直以来,我希望自己的孩子关注两个基本点:
1.培养一种思维习惯,用历史的,跨界的眼光思考问题,关注发展和变化。
2.掌握笛卡尔方法论,将从线索到结论的过程通过一种工程框架串联起来。
这也是我自己一直以来关注的。
当看到一些我平时发布的博客,朋友圈之后,很多人不能理解我为什么能为这么显而易见的简单东西兴奋这么久,我无法反驳,因为这些东西确实简单,但我又可以反驳,因为它们并不是很显而易见,若非老师或者书本告诉你,你自己以为的那部分在哪里?简单的,有多少人可以不用任何四则混合运算知识,将绳子分成5等份?复杂的,如果所有的书籍和记忆消失了,人类有多大的几率比5万年前的原始智人更强?
传统教育让我们注重客观,少说“我以为”,但我以为这是不正确的,智人之跃入文明,全在形而上。

浙江温州皮鞋湿,下雨进水不会胖。

以上是关于手工计算对数的方法和对应的C代码的主要内容,如果未能解决你的问题,请参考以下文章

10个JavaScript代码片段,使你更加容易前端开发。

c ++试图找出对数计算

C中任意整数基数的对数函数

ASP.net MVC 代码片段问题中的 Jqgrid 实现

计算对数

对数器的使用