2016-03-29 4 views
1

Я только начал делать первые шаги в обучении кодированию и общем (начиная с C#), и сейчас я изучаю книгу. Книга оставляет вопросы в конце каждой главы. В настоящее время я не уверен, как это сделать. Вопрос заключается в следующем:Подсчет бесконечной серии 1/n

Вопрос: Напишите программу, которая рассчитывает сумму (с точностью 0,001) следующей последовательности: 1 + 1/2 - 1/3 + 1/4 - 1/5 + ... 1/п

книга дала следующие рекомендации для решения этой проблемы:

Направляющие линии: накапливают сумму последовательности в переменной внутри некоторое время петли (смотрите главу «петли»). На каждом шаге сравнивайте старую сумму с новой суммой. Если разница между двумя суммами Math.Abs ​​(current_sum - old_sum) меньше требуемой точности (0,001), расчет должен завершиться, потому что разница постоянно уменьшается и точность постоянно увеличивается на каждом шаге цикла. Ожидаемый результат: 1.307

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

Вот мой код. Я знаю, что его полицейский использовал формат {N: 2}, но я не уверен, как действовать. Очень понравилась бы помощь! Благодаря!

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 

namespace Demo 
{ 
    class Program 
{ 
    static void Main() 
    { 

     Console.Write("Please enter n: "); 
     double counter = double.Parse(Console.ReadLine()); 
     double sum = 1 + AddSum(counter); // calculate infinite sum 
     Console.WriteLine("Sum = {0:N3}", sum); 



    } 


    static double AddSum(double n) 
    { 
     double a = 0; 

     for (double i = 1; i < n; i++) 
     { 
      if(i % 2 == 0) 
      { 
       a -= 1/(i +1); // calculates negative fractions 
      } 

      else 
      { 
       a += 1/(i +1); // calculates positive fractions 
      } 
     } 

     return a; 
    } 

} 
+0

Что является критерием для завершения программы Это не номер, введенный пользователем. Это «Если разница между двумя суммами Math.Abs ​​(current_sum - old_sum) меньше требуемой точности (0,001), расчет должен завершиться». Затем вы возвращаете результат. Поэтому вы не должны просить пользователя ввести n –

+0

Я не знал, как начать решение проблемы, поэтому решил обратиться к пользователю с просьбы. Надеюсь, что я смогу сначала распечатать начальную сумму, а затем решить остальную часть проблемы в отношении требуемой точности. – Nate

ответ

-1

Возможно, вы захотите следовать приведенному руководству: не вводите n, поскольку программа должна завершиться автоматически. Где предложенный цикл while? Вы подумаете ответ быстро себя тогда :-)

Может быть, начать с этого:

static void Main() 
{ 
    decimal result = 1; 
    int n = 1; 
    do 
    { 
     // remember the current result 
     result += 1/(++n * DetermineMultiplier(n)); 
    } while (/* precision calculation here */); 

    // print result and n 
} 

private int DetermineMultiplier(int n) 
{ 
    // return -1 if n is odd, 1 if it is even 
} 
+0

Этот подход страдает от ошибок депрессии. Вы всегда должны суммировать положительные и отрицательные термины отдельно. – Enigmativity

+0

@ Энигматичность: Пожалуйста, уточните и/или отредактируйте ответ. Я оставил вычисление точности открытым, поэтому ваш комментарий не применяется. –

+0

Взгляните на https://en.wikipedia.org/wiki/Loss_of_significance & https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Weaknesses/ – Enigmativity

-1

Как вы не хотите указывать n и единственное условием выхода является точной проверкой, вы можете сделать это ,

static double AddSum() 
{ 
    double a = 0; 
    double oldvalue; 
    int i = 1; 

    do 
    { 
     oldvalue = a; 
     a += (i % 2 == 0) ? (double)-1/(i + 1) : (double)1/(i + 1); 

     i++; 
    }while (!(i != 1 && Math.Abs(a - oldvalue) < 0.0001)); // we can remove i!=1 if we know and hard code first default value 

    return a; 
} 

Работа Example

+0

Этот подход страдает от ошибок депрессии. Вы всегда должны суммировать положительные и отрицательные термины отдельно. – Enigmativity

+0

@ Энигматичность Извините, я не совсем понимаю, что вы имеете в виду? не могли бы вы рассказать? мы можем улучшить ответ. –

+0

Взгляните на https://en.wikipedia.org/wiki/Loss_of_significance & https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Weaknesses/ – Enigmativity

0

Вот пример, который не страдает от subtractive cancellation:

static double AddSum() 
{ 
    double pos = 1.0; 
    double neg = 0.0; 

    double delta = 0.001; 
    double current = pos + neg; 
    double previous = pos + 2.0 * delta; 

    int i = 2; 
    while (Math.Abs(current - previous) >= delta) 
    { 
     if (i % 2 == 0) 
     { 
      pos += 1.0/i; 
     } 
     else 
     { 
      neg -= 1.0/i; 
     } 
     previous = current; 
     current = pos + neg; 

     i++; 
    } 

    return current; 
} 
+0

Не могли бы вы подробнее остановиться на использовании дельта? Я не понимаю строку, где он говорит double previous = pos + 2 * delta – Nate

+0

@Nate - Это значит, что выражение 'Math.Abs ​​(current - previous)> = delta' истинно. – Enigmativity

+0

@Nate - Извините, у меня была ошибка в коде. Я заменил '0,001' в состоянии цикла' while' с 'delta'. – Enigmativity