程序近似正弦和余弦值的问题

2024-09-28 23:25:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图写一个程序,它以度为单位,根据用户选择的一些给定项来近似sin和cos值。万一你不知道 how寻找罪与果。所以,我现在的代码是:

import math
def main():
    print()
    print("Program to approximate sin and cos.")
    print("You will be asked to enter an angle and \na number of terms.")
    print("Written by ME")
    print()

    sinx = 0
    cosx = 0

    x = int(input("Enter an angle (in degrees): "))
    terms = int(input("Enter the number of terms to use: "))
    print()

    for i in range(1, terms+1):
        sinx = sinx + getSin(i, x)
        cosx = cosx + getCos(i, x)

    print(cosx, sinx)

def getSin(i, x):
    if i == 1:
        return x
    else:
        num, denom = calcSinFact(i, x)
        sin = num/denom
        return sin

def getCos(i, x):
    if i == 1:
        return 1
    else:
        num, denom = calcCosFact(i, x)
        cos = num/denom
        return cos

def calcSinFact(i, x):
    if i % 2 == 1:
        sign = -1
    if i % 2 == 0:
        sign = +1
    denom = math.factorial(i*2-1)
    num = sign * (x**(i*2-1))
    return num, denom

def calcCosFact(i, x):
    if i % 2 == 1:
        sign = -1
    if i % 2 == 0:
        sign = +1
    denom = math.factorial(i*2)
    num = sign * (x**(i*2))
    return num, denom

它运行,但是如果我使用上面图片中的例子,我得到cos=-162527117141.85715和sin=-881660636823.117。很明显有什么不对劲。在上图中,答案应为cos=0.50000000433433和sin=0.866025445100。我假设这是我在第一个循环中把值相加的方式,但我可能错了。感谢任何帮助!在


Tags: andtoreturnifdefmathsincos
3条回答

正如Russell Borogove's comments中指出的,这里有几个问题。在

第一个问题是你使用的公式

enter image description here

(见wikipedia)期望x是弧度而不是度数。绕一个圆一圈是360度或2*pi,因此可以通过乘以pi/180将度数转换为弧度,如下python代码中所示,这样可以错误地获得90度的sin。在

>>> math.sin(90)
0.8939966636005579
>>> math.sin(90*math.pi/180)
1.0

问题2是代码的其余部分。正如在评论中指出的,有一些bug,找到它们的最好方法是使用一些战略性的print语句。然而,你可以用更少的代码行来编写你的程序,而简单的程序往往会有更少的错误,如果它们确实有问题,则更容易调试。在

因为这是一个作业,我不会为您做,但是一个相关的例子是sinh(x)的系列。在

enter image description here

(再次来自维基百科)

您可以使用Pythonlist comprehension在“one shot”中生成术语。可以对列表进行printed和summed来获得结果,如下面的程序所示

^{pr2}$

这个程序的输出是

[1.5707963267948966, 0.6459640975062462, 0.07969262624616703, 0.004681754135318687, 0.00016044118478735975]
2.30129524587 2.30129890231

我直接从求和的数学公式中生成了Python列表理解代码,它在左侧以“Sigma”表示法方便地给出。你也可以用同样的方式产生罪恶和罪恶。你需要的一个缺少的成分是系列中每一点的符号。数学公式告诉你你需要(-1)n。Python的等价物是(-1)**n,它可以被安排到列表理解代码的适当位置。在

下面是一个改进版本:

from math import radians
import sys

# version compatibility shim
if sys.hexversion < 0x3000000:
    # Python 2.x
    inp = raw_input
    rng = xrange
else:
    # Python 3.x
    inp = input
    rng = range

def type_getter(type):
    def fn(prompt):
        while True:
            try:
                return type(inp(prompt))
            except ValueError:
                pass
    return fn
get_float = type_getter(float)
get_int   = type_getter(int)

def calc_sin(theta, terms):
    # term 0
    num    = theta
    denom  = 1
    approx = num / denom
    # following terms
    for n in rng(1, terms):
        num *= -theta * theta
        denom *= (2*n) * (2*n + 1)
        # running sum
        approx += num / denom
    return approx

def calc_cos(theta, terms):
    # term 0
    num    = 1.
    denom  = 1
    approx = num / denom
    # following terms
    for n in rng(1, terms):
        num *= -theta * theta
        denom *= (2*n - 1) * (2*n)
        # running sum
        approx += num / denom
    return approx

def main():
    print(
        "\nProgram to approximate sin and cos."
        "\nYou will be asked to enter an angle and"
        "\na number of terms."
    )

    theta = get_float("Enter an angle (in degrees): ")
    terms = get_int  ("Number of terms to use: ")

    print("sin({}) = {}".format(theta, calc_sin(radians(theta), terms)))
    print("cos({}) = {}".format(theta, calc_cos(radians(theta), terms)))

if __name__=="__main__":
    main()

请注意,由于麦克劳林级数以x=0为中心,接近0的θ值收敛得更快:calc_sin(radians(-90), 5)为-1.00000354258,而{}为-0.444365928238(与-1.0的正确值相差约157000倍)。在

首先,一些注意事项。最好在上一次打印结束时打印\n,或者在下一次打印的开始处打印print()。 使用调试工具、使用logging模块或仅使用print并通过将预期值与返回值进行比较来查找错误,这是很有用的。在

下面是一个对我有用的代码:

import math

def main():
    print()
    print("Program to approximate sin and cos.")
    print("You will be asked to enter an angle and \na number of terms.")
    print("Written by ME")
    print()

    sinx = 0
    cosx = 0

    x = int(input("Enter an angle (in degrees): "))
    terms = int(input("Enter the number of terms to use: "))
    print()

    x = x / 180.0 * math.pi; # added

    for i in range(1, terms+1):
        sinx = sinx + getSin(i, x)
        cosx = cosx + getCos(i, x)

    print("Cos:{0}, Sinus:{1}".format(cosx,sinx)); # changed

def getSin(i, x):
    if i == 1:
        return x
    else:
        num, denom = calcSinFact(i, x)
        sin = float(num)/denom # changed
        return sin

def getCos(i, x):
    if i == 1:
        return 1
    else:
        num, denom = calcCosFact(i, x)
        cos = float(num)/denom # changed
        return cos

def calcSinFact(i, x):
    if i % 2 == 1:
        sign = +1 # changed
    if i % 2 == 0:
        sign = -1 # changed
    denom = math.factorial(i*2-1)
    num = sign * (x**(i*2-1))
    return num, denom

def calcCosFact(i, x):
    if i % 2 == 1:
        sign = +1 # changed
    if i % 2 == 0:
        sign = -1 # changed
    denom = math.factorial(i*2-2) # changed
    num = sign * (x**(i*2-2)) # changed
    return num, denom

我改变了什么?(我希望我不会忘记什么)

  1. 您的sign变量错误。恰恰相反。所以我改变了条件中的符号。在
  2. 这可能不是必需的,但是当您将num除以denom时,我添加了从int到float的转换。在
  3. 根据definition of the approximation,输入x是以弧度表示的。所以我增加了从度到弧度的转换。x = x / 180.0 * math.pi;
  4. 您在calcCosFact中的索引错误。它总是高出2。(即4代替2,8代替6…)

我得到了这个结果: 输入角度(以度为单位):180输入要使用的术语数:5 成本:-0.97602221624, 窦:0.00692527070751在

现在应该是对的。当你需要快速计算数学时,我也可以推荐WolphramAlpha。在

相关问题 更多 >