Что не так с этим исходным кодом для синуса? - PullRequest
1 голос
/ 27 октября 2019

Я достаточно хорошо разбираюсь в синтаксисе Java и просто решил применить его, создав код для синуса на основе алгоритма, который я создал ранее. Я знаю, что Math.sin помогает вам оценить синус, но я просто для удовольствия решил создать свой собственный исходный код. Однако углы между 60 ° и 120 °, а также между 240 ° и 300 ° дают неправильные ответы, и я не знаю почему. Может ли кто-нибудь помочь мне найти ошибку? Я попробовал все, чтобы обнаружить это, но не смог.


    import java.util.Scanner;

    public class Sine {
       public static void main(String[] args) {
          // This code solves sine according yo the general expansion of sine
          // sin x = x - x³/3! +x^5/5! - x^7/7! +...

          Scanner scanner = new Scanner(System.in);
          double answer = scanner.nextDouble();
          scanner.close();
          answer = simplify(answer);
          answer = converttoradian(answer);
          answer = continued(answer);
          System.out.println(answer);
       }

       // This Makes all the angles that are more than 360
       // To become less than 360 and Generates the simplified
       // Angles for obtuse and reflex angles

       static double simplify(double x) {
          if (x >= 360) {
             x = x - 360;
             return simplify(x);
          }
          else if (x <= -360) {
             x = x + 360;
             return simplify(x);
          }
          else if (x > 90 && x <= 270) {
             x = 180 - x;
             return x;
          }
          else if (x >= 270) {
             x = x - 360;
             return x;
          }
          else if (x <= -90 && x > -270) {
             x = -x - 180;
             return x;
          }
          else if (x <= -270) {
             x = x + 360;
             return x;
          }
          else {
             return x;
          }
       }

       // Simple enough and explains itself
       // Converts the angles to radian

       static double converttoradian(double d) {
          d *= Math.PI;
          d /= 180.0;
          return d;
       }

       // This Method about to open generates each term and adds them together
       // The number of terms solved in this case is 33

       static double continued(double d) {
          double answer = 0.0;
          int index = 1;
          double one = d;
          for (int i = 0; i < 33; i++) {
             double result = 0.0;
             for (int x = 1; x < index; x++) {
                d = d * one;
             }
             long here = factorial(index);
             result = d / here;
             if ((index - 1) % 4 == 0) {
                answer = answer + result;
                index = index + 2;
             }
             else {
                answer = answer - result;
                index = index + 2;
             }
          }
          return answer;
       }

       // Evaluates factorials

       static long factorial(int n) {
          long one = 1;
          long m = (long) n;
          if (m == 0 || m == 1) {
             one = 1;
             return one;
          }
          else {
             while (m > 1) {
                one *= m;
                m--;
             }
             return one;
          }
       }
    }

1 Ответ

0 голосов
/ 27 октября 2019

В вашей программе было много всего и немного ненужного кода. Вы были на правильном пути, хотя. Я внес некоторые изменения для упрощения расчетов. Вы должны быть в состоянии следовать за ними.

В частности.

  1. Чередуйте знак. Начните с sign = 1, затем установите sign = -sign для последующих терминов.
  2. Для знаменателя и факториала я просто использовал цикл for, начиная с 1 и увеличивая на 2, чтобы получить 1,3,5,7
  3. Для степеней одного и того же значения я просто умножил d на dSquared константу, чтобы добиться того же.
  4. Я переписал факториал, чтобы упростить его.
  5. Чтобы уменьшить большие значения d, я просто использовал оператор remainder, чтобы получить их меньше 360.
  6. Я добавил несколько операторов печати, чтобы показать ход вычислений и убедиться, что все работает правильно.
  7. И, наконец, максимальный факториал, который уместится в long, составляет 20!. После этого они становятся отрицательными из-за переполнения. Таким образом, количество терминов необходимо уменьшить.

public class Sine {
   public static void main(String[] args) {

      // This code solves sine according yo the general expansion of sine
      // sin x = x - x³/3! +x^5/5! - x^7/7! +...

      for (double degrees = 0; degrees < 700; degrees += 17) {
         double simplified_degrees = simplify(degrees);
         System.out.println("simplified_degrees = " + simplified_degrees);
         double radians = converttoradian(simplified_degrees);
         System.out.println("radians = " + radians);

         double sin = continued(radians);
         System.out.println(sin);
         System.out.println(Math.sin(radians));
         System.out.println("------------------------------------------");
      }
   }
   // This Makes all the angles that are more than 360
   // To become less than 360 and Generates the simplified
   // Angles for obtuse and reflex angles
   static double simplify(double x) {

      x = x % 360;

      return x;
   }
   // Simple enough and explains itself
   // Converts the angles to radian

   static double converttoradian(double d) {
      return Math.PI / 180. * d;
   }
   // This Method about to open generates each term and adds them together
   // The number of terms solved in this case is 33
   static double continued(double d) {
      double result = 0;
      double sign = 1;
      double dSquared = d * d;

      int pow = 1;
      for (int pow = 1;  pow < 21; pow += 2) {

         long fact = factorial(pow);
         System.out.println("d = " + d + ", fact = " + fact + ", pow = " + pow
               + ", sign = " + sign);
         result = result + (d / fact) * sign;

         d *= dSquared; // effective powers 3, 5, 7,9
         sign = -sign; // alternate sign for every other term

      }
      return result;
   }
   // Evaluates factorials
   static long factorial(int n) {
      if (n == 0 || n == 1) {
           return 1;
      }
      long fact = 1;
      for (long i = 2; i <= n; i++) {
          fact *= i;
      }
      return fact;
    }
}
...