Почему именно десятичная.Разделить(int, int) работу, но не (int / int)?


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

7 87

7 ответов:

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

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

int a = 42;
int b = 23;
double result = (double)a / b;

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

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

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

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 в десятичные перед возвращением десятичного значения (точного), где as 4/5 рассматривается как целочисленное деление и возвращает 0

вы хотите бросить номерами:

double c = (double)a/(double)b;

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

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();
        }

Если вы ищете 0

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

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

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

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

в финансовых системах, часто требование что мы можем гарантировать некоторое количество (основание-10) точность десятичных знаков. Это вообще невозможно, если входные / исходные данные находятся в базе-10, но мы выполняем арифметику в базе-2 (потому что количество десятичных знаков, необходимых для десятичного расширения числа, зависит от базы; одна треть занимает бесконечно много десятичных знаков, чтобы выразить в базе-10 как 0.333333... но он принимает только один десятичный базы-3: 0.1).

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