在 SQL Server 中使用泰勒级数计算指数函数






4.66/5 (14投票s)
在数据库编程中,不使用游标的迭代是一种艺术。在本文中,我尝试使用泰勒级数计算指数函数。
引言
在数学中,指数函数是 函数 ex,其中 e 是一个数字(大约为 2.718281828),使得函数 ex 是它自身的 导数。指数函数可以通过多种方式 定义,最常见的定义方式之一是使用 无限泰勒级数。
泰勒级数是一种将 函数表示为 无穷级数,其各项通过在单个点计算函数 导数的值来计算。
泰勒级数的概念由英国数学家 布鲁克·泰勒于 1715 年正式提出。如果泰勒级数以零为中心,则该级数也称为 麦克劳林级数,以苏格兰数学家 科林·麦克劳林命名,他在 18 世纪广泛使用泰勒级数的这个特殊情况。
我以两种不同的方式实现了指数函数,一种使用递归,另一种不使用。我使用了 公共表表达式;有关使用和实现 CTE 的更多详细信息,请查看这篇文章:SQL Server 中的 CTE。
使用 CTE 实现
为了弄清楚我在代码中做了什么,如图所示,我需要计算数字的阶乘和它们的幂。我使用 CTE 创建一个带有标识行的表。
CTE 中默认的递归次数为 100,我将标识号限制为 100,因此该级数持续 100 次。
;WITH CTE AS
(SELECT cast(1.0 as float) AS rowNumber
UNION ALL
SELECT cast(cast(rowNumber as float)+1 as float)
from CTE
WHERE rowNumber < 100)
select *
FROM CTE
结果是数字 1 到 100
然后对于每个数字,我需要它的阶乘。为此,我添加了一个额外的列,它是对每一行进行乘法运算后的结果。
;WITH CTE AS
(SELECT cast(1.0 as float) AS i,
cast(1.0 as float) AS factorial
UNION ALL
SELECT cast(cast(i as float)+1 as float),
cast(cast(factorial as float)*(cast(i as float)+1)as float)
FROM CTE
WHERE i < 100)
select * from CTE
结果如下
最后,对于每一行,我需要 x 的 rowNumber
的幂,并使用幂函数。
首先创建的行是 @x ^1 的结果。在第二行中,我从 rowNumber +1 开始计算幂。
declare @x float = 3
;WITH CTE AS
(SELECT cast(1.0 as float) AS rowNumber,
cast(1.0 as float) AS factorial,
cast(@x as float)as [power]
UNION ALL
SELECT cast(cast(rowNumber as float)+1 as float),
cast(cast(factorial as float)*(cast(rowNumber as float)+1)as float),
cast(power(cast(@x as float),cast(rowNumber+1 as float)) as float)
FROM CTE
WHERE rowNumber < 100)
select * from CTE
结果如下
最后,我通过动态连接将每一行的幂除以阶乘,并将它们相加。
create FUNCTION dbo.EpowerX(@x int)
RETURNS FLOAT
AS
BEGIN
declare @Result float
;WITH N AS
(SELECT cast(1.0 as float) AS i,
cast(1.0 as float) AS f,
cast(@x as float)as g
UNION ALL
SELECT cast(cast(i as float)+1 as float),
cast(cast(f as float)*(cast(i as float)+1)as float),
cast(power(cast(@x as float),cast(i+1 as float)) as float)
FROM N
WHERE i < 100)
select @Result=isnull(@Result,cast(@x as float))+ cast(g as float)/cast(f as float)
from N
where i !=1
OPTION (MAXRECURSION 0);
RETURN @Result + 1
END
select cast(cast(dbo.EpowerX(30) as float) as decimal(38,3)) as myex
select cast(cast(EXP(30)as float) as decimal(38,3)) sqlexp
结果是