【问题标题】:Computing sine and cosine in Java用Java计算正弦和余弦
【发布时间】:2016-03-05 09:55:09
【问题描述】:
import java.util.*;
import java.math.*;
public class SinCos{
    public static void main(String args[]){
        Scanner kb=new Scanner(System.in);
        System.out.println("Enter the angle for cosine: ");
        double anglecos=kb.nextDouble();
        System.out.println("Enter the number of expansions required:");
        double n=kb.nextDouble();
        System.out.println("Enter the angle for sine:");
        double anglesin=kb.nextDouble();
        System.out.println("Enter the number of expansions required:");
        double n2=kb.nextDouble();
        System.out.println("Cosine: "+workCos(anglecos,n));
        System.out.println("Sine: " +workSin(anglesin,n2));
    }

    public static double workCos(double angle, double num){
        double ans = 1;
        double ans2=0;

        for(int n = 1;((Math.round(ans * 10000.0) / 10000.0)==ans2)&&n>10; n++) {
            double times=2*n;
            ans2=Math.round(ans * 10000.0) / 10000.0;
            ans += Math.pow(-1, n) * Math.pow(angle, 2*n) / fact(times);
        }

        return ans;
    }

    public static double workSin(double angle, double num){
        double ans = 0;
        double ans2=0;
        double t;
        double t2;

        for(int k=0;(Math.round(ans * 10000.0) / 10000.0)==ans2;k++){
            ans2=Math.round(ans * 10000.0) / 10000.0;
            double times=2*k+1;
            ans += Math.pow(-1, k - 1) * Math.pow(angle, 2*k - 1) / fact(times);


        } return ans;
    }

    public static double fact(double num){
        if(num==0||num==1){
            return 1;
        }
        else{
            return num* fact(num-1);
        } 
    }
}

我一直在尝试使用泰勒定理计算正弦和余弦。但是,我最后给出的答案与实际答案相去甚远。

我的代码中的最后一个方法给出了阶乘。其他两种方法使用泰勒定理计算值。这两种方法的想法是继续计算,直到答案彼此相差不大。

【问题讨论】:

  • JDK中有方法叫Math.cosMath.sin,使用它们。
  • 是的,我知道。但我想用泰勒的系列来计算它们,因为这是一个作业
  • 这两种方法都应该返回0,这是问题所在的一个重要提示。检查您的循环终止条件。此外,您没有使用“扩展”,这几乎可以肯定是一个错误。旁注:阶乘几乎总是以整数计算,并且可以通过使用 switch 语句轻松缓存(因为序列增长速度有多快)。

标签: java trigonometry


【解决方案1】:

我早就忘记了泰勒定理(虽然我早就知道了),所以我不会深入研究你的实现。但是,我确实看到了这一点:

for(int n = 1;((Math.round(ans * 10000.0) / 10000.0)==ans2)&&n>10; n++)

这是没有意义的,因为这个循环会因为&& n>10 而立即退出,这在第一次通过它时是不正确的。还要检查第二个 for 循环,因为它也不检查 for 循环中声明的 int k = 0 的值。我确定这是问题所在,但可能不是唯一的问题。

【讨论】:

    【解决方案2】:

    首先,我同意 Vucko,你应该去掉 n>10 但我认为这只是一个错误。

    我假设这部分是为了避免溢出错误。

    ((Math.round(ans * 10000.0) / 10000.0)==ans2)
    

    这应该更改,因为您可能希望循环在此为真时停止,如果为假则继续循环。在 for 循环 for(A;B;C) 中,如果 B 为真,则循环将继续进行,因此您应该将其更改为以下内容。

    ((Math.round(ans * 10000.0) / 10000.0)!=ans2)
    

    改为手动检查 Nans 怎么样(我清理了你的代码,虽然它可能更有效)

    public static double workCos(double angle, double num){
        double ans = 0;
        for(int n = 0; n < num; n++) {
            double currAns = Math.pow(-1, n) * Math.pow(angle, 2*n) / fact(2*n);
            if(Double.isNaN(currAns))
                break;
            ans += currAns;
        }
        return ans;
    }
    

    【讨论】:

    • 不用担心 NaN!泰勒公式为0 &lt;= angle &lt;= 2*pi 快​​速收敛......并为0 &lt;= angle &lt;= pi/2 提供准确的结果 - 我认为 OP 希望在 2 个连续值之间的差异小于 1e-4 时立即停止迭代
    【解决方案3】:

    泰勒级数的输入必须是弧度而不是度数。

    【讨论】:

      猜你喜欢
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 1970-01-01
      • 2017-10-06
      相关资源
      最近更新 更多