\sin x = c _ 0 + c _ 1 x + c _ 2 x ^ 2 + c _ 3 x ^ 3 + c _ 4 x ^ 4
我们从 x = 0 开始逼近 \sin x,那么因为 \sin 0 = 0,所以我们要让多项式的值在 x = 0 时为 0,即 c _ 0 = 0。
\sin x = c _ 1 x + c _ 2 x ^ 2 + c _ 3 x ^ 3 + c _ 4 x ^ 4
同时,我们也需要让多项式的斜率(倾斜程度,具体见下一节)在 x = 0 时与 \sin x 相等,于是我们对 \sin x 进行求导,即 (\sin x)' = \cos x。当 x = 0 时,\cos x = 1。
我们又对多项式进行求导,得 (c _ 1 x + c _ 2 x ^ 2 + c _ 3 x ^ 3 + c _ 4 x ^ 4)' = c _ 1 + 2c _ 2 x + 3c _ 3 x ^ 2 + 4c _ 4 x ^ 3。当 x = 0 时,c _ 1 + 2c _ 2 x + 3c _ 3 x ^ 2 + 4c _ 4 x ^ 3 = c _ 1。
所以 c _ 1 = 1。
\sin x = x + c _ 2 x ^ 2 + c _ 3 x ^ 3 + c _ 4 x ^ 4
同时,为了在 x = 0 处附近的误差不太大,要让多项式斜率的变化程度与 \sin x 在 x = 0 处也相等,于是对其进行二阶求导。
当 x = 0 时,
(\sin x)'' = -\sin x = 0(x + c _ 2 x ^ 2 + c _ 3 x ^ 3 + c _ 4 x ^ 4)'' = 2c _ 2 + 6c _ 3 x + 12c _ 4 x ^ 2 = 2c _ 2
所以 2c _ 2 = 0,即 c _ 2 = 0。
\sin x = x + c _ 3 x ^ 3 + c _ 4 x ^ 4
继续如法炮制。
当 x = 0 时,
(\sin x)''' = -\cos x = -1(x + c _ 3 x ^ 3 + c _ 4 x ^ 4)''' = 6c _ 3 + 24c _ 4 x = 6c _ 3
把这个公式应用到 y = \displaystyle \frac 1 2 x ^ 2 - 3x + 1 中,则
\begin {align*}
y' &= \lim \limits _ {\Delta x \to 0} \frac {\displaystyle \frac 1 2 (x + \Delta x) ^ 2 - 3 (x + \Delta x) + 1 - (\frac 1 2 x ^ 2 - 3x + 1)} {\Delta x} \\
&= \lim \limits _ {\Delta x \to 0} \frac {\displaystyle \frac 1 2 x ^ 2 + x \Delta x + \frac 1 2 \Delta x ^ 2 - 3x - 3 \Delta x + 1 - \frac 1 2 x ^ 2 + 3x - 1)} {\Delta x} \\
&= \lim \limits _ {\Delta x \to 0} \frac {x \Delta x + \frac 1 2 \Delta x ^ 2 - 3 \Delta x} {\Delta x} \\
&= \lim \limits _ {\Delta x \to 0} x + \frac 1 2 \Delta x - 3 = x - 3
\end {align*}
所以当 x = 0 时斜率为 -3。
代码示例
from typing import Union
from math import pi, sqrt
# angle:以弧度为单位,decimal_digits:精确的小数位数,返回值为(cos, sin)
def taylor(angle: Union[int, float], decimal_digits: int = 6):
angle %= 2 * pi
res = 0
mul = 1
num = 1
while True:
nxt = res + angle ** num / mul
mul *= (num + 1) * (num + 2)
num += 2
nxt -= angle ** num / mul
mul *= (num + 1) * (num + 2)
num += 2
if (round(nxt, decimal_digits + 1) == round(res, decimal_digits + 1)):
res = nxt
break
res = nxt
sin_ans = round(res, decimal_digits)
cos_ans = (1 - res ** 2) ** 0.5
tan_ans = round(res / (1 - res ** 2) ** 0.5, decimal_digits) if cos_ans != 0 else float('inf')
cos_ans = round(cos_ans, decimal_digits)
if cos_ans == -0.0:
cos_ans = 0.0
if sin_ans == -0.0:
sin_ans = 0.0
return cos_ans, sin_ans, tan_ans
n = float(input())
n = n / 180 * pi
x, y, tangent = taylor(n)
print(x, y, tangent)