Почему Decimal.Divide (int, int) работает, но не (int / int)?

107

Почему мне возвращается разделение двух 32-битных чисел int, когда (int / int) мне возвращается 0, но если я использую, Decimal.Divide()я получаю правильный ответ? Я ни в коем случае не парень с С #.

Лиам
источник
1
Вы можете привести конкретный пример? Decimal - это тип, отличный от Int32.
Groo
Кстати, я обнаружил, что Decimal.Divide принимает в качестве входных данных только десятичные числа.
Рави
Decimal.Divide также работает с целыми числами.
Thamarai T

Ответы:

217

int- целочисленный тип; деление двух целых чисел выполняет целочисленное деление, т.е. дробная часть усекается, так как ее нельзя сохранить в типе результата (также int!). Decimal, напротив, имеет дробную часть. При вызове Decimal.Divideваши intаргументы неявно преобразуются в Decimals.

Вы можете принудительно использовать нецелочисленное деление для intаргументов, явно приведя хотя бы один из аргументов к типу с плавающей запятой, например:

int a = 42;
int b = 23;
double result = (double)a / b;
Конрад Рудольф
источник
2
Хороший ответ. Я также попробовал Decimal.Divide (a, b), который дал тот же результат.
Baxter
6

В первом случае вы выполняете целочисленное деление, поэтому результат обрезается (десятичная часть обрезается), и возвращается целое число.

Во втором случае целые числа сначала преобразуются в десятичные числа, а результат - десятичный. Следовательно, они не усекаются, и вы получаете правильный результат.

Эндрю Роллингс
источник
4

Следующая строка:

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
Фредрик Мёрк
источник
2

Я считаю, что Decimal.Divide(decimal, decimal)неявно преобразует 2 аргумента типа int в десятичные числа, прежде чем вернуть десятичное значение (точное), где 4/5 рассматривается как целочисленное деление и возвращает 0

Гишу
источник
1

Вы хотите бросить числа:

double c = (двойной) a / (двойной) b;

Примечание. Если какой-либо из аргументов в C # является двойным, используется двойное деление, которое приводит к двойному. Итак, следующее тоже будет работать:

двойной c = (двойной) 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();
        }
Джайдип Шил
источник
0

Если вы ищете ответ 0 <a <1, int / int будет недостаточно. int / int выполняет целочисленное деление. Попробуйте преобразовать один из int в double внутри операции.

Брайан
источник
1
Int32 - целое число со знаком, вы имели в виду 0 <ответ <1?
Groo,
0

В моем случае выше ничего не работало.

я хочу разделить 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.

Альп Алтунель
источник
-1

Ответ, помеченный как таковой, почти готов, но я думаю, что стоит добавить, что есть разница между использованием double и decimal.

Я бы не стал лучше объяснять концепции, чем Википедия, поэтому я просто предоставлю указатели:

арифметика с плавающей запятой

десятичный тип данных

В финансовых системах часто требуется, чтобы мы могли гарантировать точность до определенного числа десятичных знаков (с основанием 10). Как правило, это невозможно, если входные / исходные данные находятся в базе 10, но мы выполняем арифметические действия в базе 2 (поскольку количество десятичных знаков, необходимых для десятичного разложения числа, зависит от базы; одна треть занимает бесконечно много десятичных знаков. места для выражения с основанием-10 как 0,333333 ..., но в основании-3 требуется только один десятичный знак: 0,1).

С числами с плавающей запятой работать быстрее (с точки зрения процессорного времени; с точки зрения программирования они одинаково просты) и предпочтительнее, когда вы хотите минимизировать ошибку округления (как в научных приложениях).

Додзё
источник
1
Ничто в вашем ответе не отвечает на исходный вопрос
Лорд Уилмор