#c# #function #multiplication
#c# #функция #умножение
Вопрос:
Я пытаюсь написать функцию, которая возвращает результат умножения всех отрицательных чисел в массиве. Если значение слишком велико для обработки, я хочу, чтобы оно возвращало значение int.MinValue .
Я закодировал это следующим образом, но это работает некорректно, и я не уверен, почему.
public int MultiNeg(int[] array)
{
List<int> negativenumbers = new List<int>();
foreach (int numbers in array)
{
if (numbers < 0)
negativenumbers.Add(numbers);
}
int multiply = 1;
foreach (int i in negativenumbers)
{
multiply = multiply * i;
if (multiply > int.MaxValue)
{
return int.MinValue;
}
}
if (multiply > int.MaxValue)
{
return int.MinValue;
}
else
{
return multiply;
}
Комментарии:
1. разве вам не нужно
multiply
какint64
для этой проверки? Или вы можете сделатьtry catch
блок, чтобы посмотреть, сможете ли вы умножить2. Вы должны описать, как это «не работает». Вы получаете неправильные результаты? Если да, то каковы ожидаемые результаты и фактические результаты, которые вы видите? Вы получаете ошибку компиляции или исключение во время выполнения? Если да, то что такое сообщение об ошибке / исключении и какая строка его вызывает?
3. Условие:
if (multiply > int.MaxValue)
всегда будетfalse
, тогда невозможно, чтобы anint
было большеint.MaxValue
.4. Это не то, о чем задается вопрос, но рассматривали ли вы возможность использования
int64
для правильного покрытия диапазона без необходимости делать это? Даже если этого недостаточно, вы можете посмотреть: docs.microsoft.com/en-us/dotnet/api /…
Ответ №1:
Вместо выполнения всей этой работы все, что вам нужно, это выполнить арифметику в виде проверяемого выражения и перехватить исключение, чтобы вернуть значение неудачного случая.
public static int MultiNeg(int[] array)
{
var negativenumbers = array.Where(x => x < 0);
int multiply = 1;
foreach (int i in negativenumbers)
{
try {
multiply = checked(multiply * i);
}
catch (OverflowException) {
return Int32.MinValue;
}
}
return multiply;
}
Бонус: вот сокращенная версия, использующая агрегированный метод Linq.
public static int MultiNeg(int[] array)
{
try {
return array.Where(x => x < 0).Aggregate(1, (x, y) => checked(x * y));
} catch (OverflowException) {
return Int32.MinValue;
}
}
Ответ №2:
Во-первых, я НИКОГДА не смогу быть> int.MaxValue, поскольку оно само по себе является int . Во-вторых, хотя @DanielGimenez опубликовал совершенно рабочий пример, я предоставляю эту альтернативу, потому что блок try-catch будет иметь негативное влияние на производительность. Если это не важно, тогда используйте его путь. Если это важно, вот альтернатива. Используйте Math.BigMul, чтобы сначала получить результат умножения (обратите внимание на использование long вместо int для результата и сравнения):
public int MultiNeg(int[] array)
{
List<int> negativenumbers = new List<int>();
foreach (int numbers in array)
{
if (numbers < 0)
negativenumbers.Add(numbers);
}
int multiply = 1;
foreach (int i in negativenumbers)
{
long value = Math.BigMul(multiply,i);
if (value > int.MaxValue || value < int.MinValue)
{
return int.MinValue;
}
else
{
multiply = multiply * i;
}
}
return multiply;
}
Вы заметите, что я также учитывал случай, когда значение multiply равно < int.MinValue , что в равной степени возможно и вероятно.