Подтвердить что ты не робот

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

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

4b9b3361

Ответ 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).

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