Основные операции с массивами

Я работаю в персонализированном классе математики, я намерен реализовать основные методы операций, чтобы они складывали, вычитали, умножали или делили простым способом без необходимости каждый раз вызывать операторы + - * /.

    public class XMath
    {
        public static double Sum(params double[] values)
        {
            double result = 0;

            if (values.Length < 1 || values is null) result = 0;
            else if (values.Length == 1) result = values[0];
            else foreach (double value in values) result += value;

            return result;
        }

        public static double Subtract(params double[] values)
        {
            double result = 0;

            if (values.Length < 1 || values is null) result = 0;
            else if (values.Length == 1) result = values[0];
            else foreach (double value in values) result -= value;

            return result;
        }

        public static double Multiply(params double[] values)
        {
            double result = 0;

            if (values.Length < 1 || values is null) result = 0;
            else if (values.Length == 1) result = values[0];
            else foreach (double value in values) result *= value;

            return result;
        }

        public static double Divide(params double[] values)
        {
            double result = 0;

            if (values.Length < 1 || values is null) result = 0;
            else if (values.Length == 1) result = values[0];
            else foreach (double value in values) result /= value;

            return result;
        }
    }

Моя проблема в том, что метод Sum работает отлично, но другие выдают неверные результаты.

Итак, если += работает, потому что -=, *= и /= нет


person Héctor Manuel Martínez Durán    schedule 24.03.2018    source источник
comment
Что вы имеете в виду, когда говорите, что они не работают? Результаты отключены или выдаются исключения?   -  person dee-see    schedule 24.03.2018
comment
@Vache они выдают неправильные результаты   -  person Héctor Manuel Martínez Durán    schedule 24.03.2018
comment
ожидаемое поведение против результата?   -  person nicecatch    schedule 24.03.2018
comment
Также следует добавить некоторую защиту от деления на 0   -  person Gregg L    schedule 24.03.2018
comment
В этих строках: if (values.Length < 1 || values is null) вы должны изменить порядок этих проверок. Эта строка вызовет исключение, когда 2-я часть условия верна, потому что 1-я часть завершится ошибкой до того, как будет проверена 2-я часть.   -  person Joel Coehoorn    schedule 25.03.2018


Ответы (3)


Основная проблема заключается в том, что вы инициализируете свою переменную result значением 0.

Предположим, что массив double[] values = new [] { 1.0, 2.0, 3.0 }, ваш метод Sum вычисляет 0 + 1 + 2 + 3, Subtract вычисляет 0 - 1 - 2 - 3, Multiply вычисляет 0 * 1 * 2 * 3 и т. д.

Дополнительный 0 не влияет на сумму, но влияет на другие операции.

Вы должны инициализировать свои операции с первым элементом массива вместо 0.

Вы также можете изучить метод Aggregate. который упростит ваш код до

values.Aggregate((x, y) => x + y);
// ...
values.Aggregate((x, y) => x - y);
// ...
values.Aggregate((x, y) => x * y);
// ...
values.Aggregate((x, y) => x / y);
person dee-see    schedule 24.03.2018
comment
Ну, это создает IEnumerable, поэтому, чтобы получить результат, я должен использовать цикл for или что-то в этом роде? - person Héctor Manuel Martínez Durán; 24.03.2018
comment
Aggregate использует IEnumerable (а массивы IEnumerable), но в вашем случае создает double. - person dee-see; 24.03.2018

Это один из примеров, когда цикл for был бы лучше, чем цикл foreach.

    public static double Sum(params double[] values)
    {
        if (values.Length < 1 || values is null) 
           return 0;
        double result = values[0];
        for(int i = 1; i < values.Length; i++)
           result += values[i];
        return result;
    }
person Kevin    schedule 24.03.2018
comment
Результат хороший, но вы изменяете исходный массив, что может привести к неожиданным результатам для вызывающей стороны. - person dee-see; 24.03.2018

Вы можете использовать Enumerable.Aggregate<TSource>(IEnumerable<TSource>, Func<TSource, TSource, TSource>) форму System.Linq

Aggregate использует IEnumerable, но в вашем случае создает double.

Пример (и массивы IEnumerable):

using System.Linq;

double[] values = new [] {5, 9, 3};

values.Aggregate((x, y) => x + y);
person Community    schedule 04.05.2018