Проблема с подсчетом суммы в C#

162
10 апреля 2019, 14:00

Задача: Даны числовой ряд и некоторое число e>0. Найти сумму тех членов последовательности ряда, модуль которых больше или равен заданному e.

Дана последовательность вида An=n!/(2n)!

Мой код:

class Program
{
    public static double fact(double f)
    {
        double fa = 1;
        for (int i = 1; i <= f; i++)
        {
            fa *= i;
        }
        return fa;
    }
    public static void Main(string[] args)
    {
        Console.Write("Enter E = ");
        double e = System.Convert.ToDouble(Console.ReadLine());
        double j = 1;
        double n = fact(j) / fact(2*j);
        double sum = 0;
        while(Math.Abs(n) >= e)
        {
            Console.WriteLine(n);
            sum += n;
            j++;
            n = fact(j) / fact(2*j);
        }
        Console.WriteLine("SUM= {0}", sum);
        Console.ReadKey();
    }

}

Возникает проблема при подсчете, когда начинаем рассматривать элемент порядком 5 и более.

Например:

A5 = fact(5)/fact(5*2); // C# выводит нам 3,30687830687831E-05

Считаем это значение вручную. Получаем => fact(5)= 120; fact(10) = 3628800;

120/3628800 = 0.00003306878

Вопрос: Почему C# не вычисляет это именно так? Из-за этого код игнорирует данные значения и по условию они не проходят в сумму.

Answer 1

Для начала вашу функцию можно переписать:

public static int fact(int f)
    {
        int fa = 1;
        for (int i = f + 1; i <= f*2; i++)
        {
            fa *= i;
        }
        return fa;
    }

Таким образом вы будете вычислять только знаменатель, уже сокращенный с числителем.
Это будет работать быстрее чем отдельно вычислять числитель и знаменатель.
Теперь чтобы вычислить член вашей последовательности:
double n = 1.0 / fact(i);

*Возвращает int потому что факториал всегда целый

Теперь, то что он отображает 3,30687830687831E-05 вместо 0.00003306878, то это дефолтный вывод для double, который выводит с число с высокой точностью, чтобы изменить вывод(если уж он вас смущает) попробуйте поменять количество выводимых цифр после запятой:
Console.WriteLine("{0:0.000000000}", n);
Такой вывод даст 9 цифр после запятой.
* Все вычисления правильные

public static void Main(string[] args)
    {
        double e = 0.00000001;
        double sum = 0.0;
        for(int i = 0;;i++){
            double n = 1.0 / fact(i);
            if(n >= e){
                sum += n;
            } else {
                break;
            }
        }
        Console.WriteLine(sum);
    }

Все работает верно.
При E = 0.00000001 подходит 8 членов
При E = 0.000000001 подходит 11 членов
И т.д.

А от модуля смысла нет, так как у вас число всегда положительное.

READ ALSO
Рисование дерева в Windows Forms

Рисование дерева в Windows Forms

у меня проблема с AutoScroll и рисованием (суть вопроса после кода)Я вот по такому коду рисую AVL- дерево:

211
Не получается удочерить GameObject к Panel, что делать?

Не получается удочерить GameObject к Panel, что делать?

При нажатие на [GameObject] в моём случае им является [Button], нужно удалить это [GameObject] и заспавнить новый [GameObject] с чем мой скрипт успешно справляется,...

185
C# много POST запросов в цикле

C# много POST запросов в цикле

Необходимо выполнить очень много POST запросов на сайт, получить ответ (типо "1,2,3" добавить в массив и отправить запросы на другой URL

189
C# WPF Как добавить attached контрол в свой User Control?

C# WPF Как добавить attached контрол в свой User Control?

Есть свой User ControlКак вложить в него например TextBlock как ето сделано в ScrollViewer?

163