Как получилось, что деление двух 32-битных чисел int (int/int) возвращается мне 0
, но если я использую Decimal.Divide()
, я получаю правильный ответ? Я отнюдь не парень С#.
Почему Decimal.Divide(int, int) работает, но не (int/int)?
Ответ 1
int
- целочисленный тип; деление двух ints выполняет целочисленное деление, т.е. дробная часть усекается, поскольку она не может быть сохранена в типе результата (также int
!). Decimal
, напротив, имеет дробную часть. Вызывая Decimal.Divide
, ваши аргументы int
неявно преобразуются в Decimal
s.
Вы можете принудительно ввести нецелое деление на аргументы int
, явно наведя хотя бы один из аргументов типа с плавающей запятой, например:
int a = 42;
int b = 23;
double result = (double)a / b;
Ответ 2
В первом случае вы выполняете целочисленное деление, поэтому результат усекается (десятичная часть прерывается) и возвращается целое число.
Во втором случае ints сначала преобразуются в десятичные числа, а результат - десятичной. Следовательно, они не усекаются, и вы получаете правильный результат.
Ответ 3
Следующая строка:
int a = 1, b = 2;
object result = a / b;
... будет выполняться с использованием целочисленной арифметики. Decimal.Divide
, с другой стороны, принимает два параметра типа Decimal
, поэтому деление будет выполняться по десятичным значениям, а не по целочисленным значениям. Это эквивалентно этому:
int a = 1, b = 2;
object result = (Decimal)a / (Decimal)b;
Чтобы проверить это, вы можете добавить следующие строки кода после каждого из приведенных выше примеров:
Console.WriteLine(result.ToString());
Console.WriteLine(result.GetType().ToString());
Выход в первом случае будет
0
System.Int32
.. и во втором случае:
0,5
System.Decimal
Ответ 4
Я reckon Decimal.Divide(decimal, decimal)
неявно преобразует свои аргументы 2 int в десятичные знаки, прежде чем возвращать десятичное значение (точное), когда 4/5 рассматривается как целочисленное деление и возвращает 0
Ответ 5
Если вы ищете 0 < a < 1, int/int будет недостаточно. int/int выполняет целочисленное деление. Попробуйте сделать один из int двойным внутри операции.
Ответ 6
Вы хотите указать числа:
double c = (double) a/(double) b;
Примечание. Если какой-либо из аргументов в С# является двойным, используется двойной разделитель, который приводит к двойному. Итак, следующее будет работать:
double c = (double) a/b;
вот небольшая программа:
static void Main(string[] args)
{
int a=0, b = 0, c = 0;
int n = Convert.ToInt16(Console.ReadLine());
string[] arr_temp = Console.ReadLine().Split(' ');
int[] arr = Array.ConvertAll(arr_temp, Int32.Parse);
foreach (int i in arr)
{
if (i > 0) a++;
else if (i < 0) b++;
else c++;
}
Console.WriteLine("{0}", (double)a / n);
Console.WriteLine("{0}", (double)b / n);
Console.WriteLine("{0}", (double)c / n);
Console.ReadKey();
}
Ответ 7
Ответ, помеченный как таковой, очень близок, но я думаю, что стоит добавить, что существует разница между использованием double и decimal.
Я бы не стал лучше объяснять понятия, чем Wikipedia, поэтому я просто предоставлю указатели:
арифметика с плавающей запятой
В финансовых системах часто требуется, чтобы мы гарантировали определенное количество (базовых 10) десятичных знаков точности. Это вообще невозможно, если входные/исходные данные находятся в базе-10, но мы выполняем арифметику в базе-2 (поскольку число десятичных знаков, необходимое для десятичного разложения числа, зависит от базы, третья - бесконечно много десятичных места для выражения в базе-10 как 0,3333333..., но в базе-3: 0,1).
Числа с плавающей запятой работают быстрее (с точки зрения процессорного времени, по программированию они одинаково просты) и предпочтительны, когда вы хотите минимизировать ошибку округления (как в научных приложениях).