Почему деление двух 32-битных целых чисел как ( int / int ) возвращает мне 0
, но если я использую Decimal.Divide()
, я получаю правильный ответ? Я ни в коем случае не С# парень.
Почему Decimal.Divide(int, int) работает, а не (int/int)?
Ответы (8)
int
— целочисленный тип; деление двух целых чисел выполняет целочисленное деление, т. е. дробная часть усекается, поскольку ее нельзя сохранить в типе результата (также int
!). Decimal
, напротив, имеет дробную часть. При вызове Decimal.Divide
ваши аргументы int
неявно преобразуются в Decimal
s.
Вы можете применить нецелочисленное деление к int
аргументам, явно приведя хотя бы один из аргументов к типу с плавающей запятой, например:
int a = 42;
int b = 23;
double result = (double)a / b;
В первом случае вы выполняете целочисленное деление, поэтому результат усекается (отсекается десятичная часть) и возвращается целое число.
Во втором случае целые числа сначала преобразуются в десятичные, и результатом является десятичное число. Следовательно, они не усекаются, и вы получаете правильный результат.
Следующая строка:
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
Я считаю, что Decimal.Divide(decimal, decimal)
неявно преобразует свои 2 аргумента int в десятичные числа, прежде чем возвращать десятичное значение (точное), где 4/5 обрабатывается как целочисленное деление и возвращает 0
Вы хотите бросить числа:
двойной c = (двойной) a/(двойной) b;
Примечание. Если какой-либо из аргументов в C# является двойным, используется двойное деление, что приводит к двойному значению. Таким образом, следующее также будет работать:
двойной с = (двойной) а/б;
вот небольшая программа:
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();
}
Если вы ищете ответ 0 ‹ a ‹ 1, int/int будет недостаточно. int / int выполняет целочисленное деление. Попробуйте привести один из int к двойному внутри операции.
В моем случае ничего не работало выше.
то, что я хочу сделать, это разделить 278 на 575 и умножить на 100, чтобы найти процент.
double p = (double)((PeopleCount * 1.0 / AllPeopleCount * 1.0) * 100.0);
%: 48,3478260869565 --> 278 / 575 ---> 0 %: 51,6521739130435 --> 297 / 575 ---> 0
если я умножу PeopleCount на 1,0, это сделает его десятичным, и деление будет 48,34 ... также умножьте на 100,0, а не на 100.
Ответ, помеченный как таковой, очень близок к этому, но я думаю, стоит добавить, что существует разница между использованием двойного и десятичного числа.
Я бы не стал объяснять концепции лучше, чем Википедия, поэтому я просто предоставлю указатели:
арифметика с плавающей запятой
В финансовых системах часто требуется, чтобы мы могли гарантировать точность определенного числа десятичных разрядов (с основанием 10). Как правило, это невозможно, если входные/исходные данные находятся в базе 10, но мы выполняем арифметику в базе 2 (поскольку количество десятичных разрядов, необходимых для десятичного расширения числа, зависит от базы; одна треть занимает бесконечно много десятичных знаков). места, чтобы выразить по основанию 10 как 0,333333..., но для этого требуется только один десятичный знак по основанию 3: 0,1).
С числами с плавающей запятой работать быстрее (с точки зрения процессорного времени; с точки зрения программирования они одинаково просты) и предпочтительнее, когда вы хотите минимизировать ошибку округления (например, в научных приложениях).