计算机是如何计算指数函数 e x e^{x} ex 的呢?

本文并不是为了探究各种编程语言中数学计算函数库对 e x e^x ex 函数的具体实现,而是提供一种计算思路,来帮助理解 e x e^x ex 函数的计算原理,并使用 C 语言来实现这个算法。

计算原理

泰勒展开

函数 exp ⁡ ( x ) = e x \exp{(x)} = e^x exp(x)=ex 的图像如下所示:

与计算对数函数 log ⁡ x \log{x} logx 相似,指数函数的计算也是对 x x x 进行处理后,使用泰勒公式进行展开计算。

指数函数 e x e^x ex 的泰勒展开如下:
e x = ∑ n = 0 n = ∞ 1 n ! x n = 1 + x + 1 2 ! x 2 + 1 3 ! x 3 + 1 4 ! x 4 + ⋅ ⋅ ⋅ + 1 n ! x n ( x → 0 , n → ∞ ) (1) e^x = \sum_{n = 0}^{n = \infty} \frac{1}{n!} x^n = 1 + x + \frac{1}{2!} x^2 + \frac{1}{3!} x^3 + \frac{1}{4!} x^4 +···+ \frac{1}{n!} x^n \quad(x \rightarrow 0, n\rightarrow \infty) \tag{1} ex=n=0∑n=∞​n!1​xn=1+x+2!1​x2+3!1​x3+4!1​x4+⋅⋅⋅+n!1​xn(x→0,n→∞)(1)
对 e x e^x ex 进行展开也是有条件的,那便是要求 x → 0 x \rightarrow 0 x→0 ,即以上的展开式只对 x x x 在 0 点附近有效。

同时,展开式的精度和 x x x 与 0 点的距离和展开的项数有关,如下:

以上是对 e x e^x ex 分别进行两项、四项、六项展开的图像。各自的误差如下:

可以看出,在相同的展开项数下, x x x 越靠近 0 点,误差越小; x x x 固定时,展开项数越多,误差越小。

参数归约化

为了能够更加精确计算出更大范围的 x x x 值的 e x e^x ex 结果,首先要对原式进行处理。

我们知道,在计算机中,实数使用 IEEE 浮点数来表示,那么计算机其实更加善于计算 2 x 2^x 2x,只要对浮点数的阶码进行处理就能计算得出 2 x 2^x 2x 的结果。

那么我们就要想办法,将以 e e e 为底的指数函数 e x e^x ex 转化为以 2 为底的指数函数 2 x 2^x 2x的计算,至少要部分转化。

我们知道:
e = 2 log ⁡ 2 e (2) e = 2^{\log_2{e}} \tag{2} e=2log2​e(2)
于是:
e x = ( 2 log ⁡ 2 e ) x = 2 x log ⁡ 2 e (3) e^x = (2^{\log_2{e}})^x = 2^{x\log_2{e}} \tag{3} ex=(2log2​e)x=2xlog2​e(3)
其中 log ⁡ 2 e ≈ 1.442695 \log_2e \approx 1.442695 log2​e≈1.442695 为常数,那么我们就成功地将计算 e x e^x ex 的问题转换为计算 2 x log ⁡ 2 e 2^{x\log_2e} 2xlog2​e 的问题了。

令 t = x log ⁡ 2 e t = x\log_2{e} t=xlog2​e,则:
e x = 2 x log ⁡ 2 e = 2 t , ( t = x log ⁡ 2 e ) (4) e^x = 2^{x\log_2{e}} = 2^{t}, \qquad (t= x^{\log_2{e}}) \tag{4} ex=2xlog2​e=2t,(t=xlog2​e)(4)
但是问题又来了,通过构造阶码的形式来计算 2 的次幂,只能计算 2 的整数次幂,而 t t t 为实数,那该怎么办呢?

这时要利用指数函数的一个性质:
a b + c = a b ⋅ a c (5) a^{b+c} = a^b \cdot a^c \tag{5} ab+c=ab⋅ac(5)
我们将 t t t 分为整数部分 m m m 与 小数部分 n n n,则:
令: t = [ t ] + ( t − [ t ] ) = m + n , ( m = [ t ] , n = t − [ t ] ) 则: 2 t = 2 m + n = 2 m ⋅ 2 n (6) 令:t = [t] + (t-[t]) = m + n, (m = [t], n = t-[t]) \\ 则:2^{t} = 2^{m+n} = 2^{m} \cdot 2^{n} \tag{6} 令:t=[t]+(t−[t])=m+n,(m=[t],n=t−[t])则:2t=2m+n=2m⋅2n(6)
对于整数次幂 2 m 2^m 2m 可通过构造阶码的形式来实现,对于小数次幂 2 n 2^n 2n ,则可对其进行再次转化为 e x e^x ex 的形式,对其进行展开:

因为 2 = e ln ⁡ 2 2 = e^{\ln2} 2=eln2 ,所以:
2 n = ( e ln ⁡ 2 ) n = e n ln ⁡ 2 (7) 2^n = (e^{\ln2})^n = e^{n\ln2} \tag{7} 2n=(eln2)n=enln2(7)
因为 n ∈ ( − 1 , 1 ) , ln ⁡ 2 ≈ 0.693147 n \in (-1,1),\ln2 \approx 0.693147 n∈(−1,1),ln2≈0.693147 ,所以 n ln ⁡ 2 ∈ ( − 0.693147 , + 0.693147 ) n\ln2 \in (-0.693147, +0.693147) nln2∈(−0.693147,+0.693147) ,已经足够接近 0 点,所以可以对其使用泰勒展开进行计算。

令 k = n ln ⁡ 2 , k ∈ ( − 0.693147 , + 0.693147 ) k = n\ln2,\quad k \in (-0.693147, +0.693147) k=nln2,k∈(−0.693147,+0.693147),则:
2 n = e k , ( k = n ln ⁡ 2 ) (8) 2^n = e^k, \quad (k = n\ln2) \tag{8} 2n=ek,(k=nln2)(8)
那么:
e x = 2 x log ⁡ 2 e = 2 t = 2 m + n ( t = x l o g 2 e , m = [ t ] , n = t − [ t ] ) = 2 m ⋅ 2 n = 2 m ⋅ e n ln ⁡ 2 = 2 m ⋅ e k ( k = n ln ⁡ 2 , n ∈ ( − ln ⁡ 2 , + ln ⁡ 2 ) ) \begin{align} e^x &= 2^{x\log_2{e}} \\ & = 2^t = 2^{m+n} \qquad (t = xlog_2{e}, m = [t], n = t - [t]) \\ & = 2^m \cdot 2^n \\ & = 2^m \cdot e^{n\ln2} = 2^m \cdot e^k \qquad (k = n\ln2, n \in (-\ln2, +\ln2)) \end{align} ex​=2xlog2​e=2t=2m+n(t=xlog2​e,m=[t],n=t−[t])=2m⋅2n=2m⋅enln2=2m⋅ek(k=nln2,n∈(−ln2,+ln2))​​
对于 e k e^k ek,根据 (1) 式:
e k = ∑ n = 0 ∞ 1 n ! k n = 1 + k + 1 2 ! k 2 + 1 3 ! k 3 + 1 4 ! k 4 + 1 5 ! k 5 + o ( k 5 ) e^k = \sum_{n = 0}^{\infty} \frac{1}{n!} k^n = 1 + k + \frac{1}{2!}k^2 + \frac{1}{3!}k^3 + \frac{1}{4!}k^4 + \frac{1}{5!}k^5 + o(k^5) ek=n=0∑∞​n!1​kn=1+k+2!1​k2+3!1​k3+4!1​k4+5!1​k5+o(k5)

实现思路

先将 x x x 乘以 log ⁡ 2 e ≈ 1.442695 \log_2{e} \approx 1.442695 log2​e≈1.442695 得到 t t t:

float x = 3.14;
float t = x * 1.442695;    // 1.442695 = log2(e)

分别取得 t t t 的整数部分 m m m 和小数部分 n n n:

m = (round)((int)(t * 2.0) / 2);
float n = t - int(t);

通过 m m m 来构造 2 m 2^m 2m:

m = (m + 127) << 23;

然后将 n n n 乘以 ln ⁡ 2 \ln2 ln2 得到 k k k:

float k = n * 0.693147;    // 0.693147 = ln(2)

再使用泰勒公式将其展开即可。

代码实现

源码

#include <stdio.h>
#include <math.h>float my_exp(float x){float t = x * 1.442695;int m = 0;float n = 0;m = (round)((int)(t * 2.0) / 2);n = t - m;m = (m + 127) << 23; n = n * 0.693147;float tmp_n = n;float j = 1;float result = 1 + n;for (int i = 2; i < 7; i++){j = j * i;tmp_n = tmp_n * n;result += tmp_n / j;}return *(float *)&m * result;
}int main(int argc, char *argv[]) {my_exp(3.14);for (int i = -10; i <= 30; i++){float x = i * 0.1;printf("x = %2.6f, my log(x) = %2.6f, log(x) = %2.6f, err = %2.6f\n", x, my_exp(x), exp(x), fabs(my_exp(x) - exp(x)));}return 0;
}

运行结果

计算机如何计算指数函数相关推荐

  1. 计算机如何计算对数函数

    计算机是如何计算对数函数 log ⁡ a x \log_a{x} loga​x 的呢? 本文并不是为了探究各种编程语言中数学计算函数库对 log ⁡ \log log 函数的具体实现,而是提供一种计算 ...

  2. 如何利用计算机计算天数,计算机如何计算两个日期之间的天数

    计算机是如何计算两个日期之间的天数的,这个问题看起来好像很简单,但是仔细一想,好像还没那么简单,月与月之间天数不一样,平年和闰年也会影响天数. 举个例子: 2017年2月1日-2017年6月1日中间有 ...

  3. 计算机数日期,计算机如何计算两个日期之间的天数

    计算机是如何计算两个日期之间的天数的,这个问题看起来好像很简单,但是仔细一想,好像还没那么简单,月与月之间天数不一样,平年和闰年也会影响天数. 举个例子: 2017年2月1日-2017年6月1日中间有 ...

  4. 监控摄像头1天存储计算机,如何计算一个摄像机一天占用多少的存储量?

    原标题:如何计算一个摄像机一天占用多少的存储量? 如何计算硬盘能存多长时间的监控视频,如何计算一个摄像机一天占用多少的存储量?现总结网上资料,做出以下言简意赅的总结: 1.IPC码流 摄像机的码流即监 ...

  5. 置信区间用计算机如何计算,正态分布置信概率和置信区间的计算机自动计算

    本文提出了不确定度分析中常用的正态分布置信概率.置信区间的几种近似算法.并根据这些算法的数学模型设计了计算程序,对实际计算结果进行了验证. 维普资讯 http://doc.xuehai.net ●匝墨 ...

  6. 围棋的分数计算机,如何计算围棋比赛的分数【围棋知识】

    原标题:如何计算围棋比赛的分数[围棋知识] ZM-GO关注 围棋比赛中分数的计算 周末围棋 围棋升段赛中会产生三个分数:大分 小分 总得分 01 大分 大分是指个人积分,嬴一盘2分,负一盘0分: 02 ...

  7. 华为计算机如何计算sina,一道华为的“简单四则运算”题

    *expStr: 表达式字符串: [输出] 无 [返回] 计算结果 int calcucate(int len, char* expStr) { //算法思路:先乘除,后加减 assert(expSt ...

  8. casio计算机如何计算标准差,怎样在卡西欧5800里计算标准差和方差,不要普通计算,用里面设计好的模式,...

    5800的SD模式,是"单变量统计计算模式" 按mode 3键进入,状态行显示SD,如下图 X 串列用于输入单变量观测数据,FREQ 串列用于输入观测数据的频度. 如果没有FREQ ...

  9. 能将无理数化为根号形式的计算机,怎么证明根号2是无理数,我们来推导和计算,还有逼格极高的算法...

    原标题:怎么证明根号2是无理数,我们来推导和计算,还有逼格极高的算法 记得上学的时候忙着考试,把心头的一些为什么都压在了脑后. 面对未知,我们大多数人都选择了默认接受,其实你不懂根号2, 比如:根号2 ...

最新文章

  1. 如何向非技术人员解释“稀疏傅里叶变换”算法?
  2. 劣质代码评析——《写给大家看的C语言书(第2版)》附录B之21点程序(一)
  3. Hyper-V 3.0部署PART 14:准备仲裁磁盘
  4. 计算机考试时间改革,武汉计算机二级考试时间和改革变化2021
  5. navicat数据库运行存储过程
  6. 你还在用 Date?建议使用 LocalDateTime 了!
  7. JUC:ConcurrentHashMap(并发容器)
  8. 理论 | 三天两夜,万字长文,吃透TCP/IP
  9. 笔记本电脑黑屏但还在运作怎么办
  10. 【转】Redis学习---阿里云Redis多线程性能增强版详解
  11. Scala学习07——隐式转换
  12. oracle weblogic 补丁,Oralce weblogic 补丁下载方法
  13. BXP的PNP的新做法(转)
  14. 181225 Matlab图解峰度kurtosis与偏度skewness
  15. 装修行业怎么找精准客户?有那些获客渠道?
  16. 人月神话(四)削足适履、提纲挈领、未雨绸缪
  17. 如何甄选出一个优秀的软件供应商?by彭文华
  18. 89. 格雷编码 Python
  19. BI神器Power Query(3)-- PQ从表格导入数据
  20. 雷电网络(二):掌握雷电网络的特点 | 区块链技术博客

热门文章

  1. 计算机网络的形成和发展
  2. javascript 方法 一直提示 对象不支持此属性或方法
  3. Linux磁盘分区初始化
  4. mysql 5.6.35anzhaung_MySQL安装与配置(5.6.12,参考乐沙弥博客,未完成)
  5. 湖北省创新型中小企业培育申报流程方法及申报时间要求指南
  6. 清亡之路(4):最受误解的东南互保
  7. Ant Design Pro右上角个人设置管理
  8. 文献解读 | m6A——程序性细胞死亡与癌症的“双刃剑”
  9. MATLAB-数据类型之复数、字符串
  10. yolov4中的route和shortcut层