手工计算对数的方法和对应的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万年前的原始智人更强?
传统教育让我们注重客观,少说“我以为”,但我以为这是不正确的,智人之跃入文明,全在形而上。

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

原文链接: https://blog.csdn.net/dog250/article/details/121289587

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

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

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/405655

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月26日 上午9:20
下一篇 2023年4月26日 上午9:20

相关推荐