Dlaczego Decimal.Divide (int, int) działa, ale nie (int / int)?

106

Dlaczego dzielenie dwóch 32-bitowych liczb int na (int / int) wraca do mnie 0, ale jeśli użyję Decimal.Divide(), otrzymam poprawną odpowiedź? W żadnym wypadku nie jestem facetem od faceta.

Liam
źródło
1
Czy możesz podać konkretny przykład? Decimal to inny typ niż Int32.
Groo
Nawiasem mówiąc, znalazłem Decimal.Divide przyjmuje tylko liczby dziesiętne jako dane wejściowe.
Ravi
Decimal.Divide działa również w przypadku liczb całkowitych jako danych wejściowych.
Thamarai T

Odpowiedzi:

215

intjest typem całkowitym; dzielenie dwóch liczb całkowitych powoduje dzielenie liczb całkowitych , tj. część ułamkowa jest obcinana, ponieważ nie można jej zapisać w typie wyniku (również int!). Decimalz kolei ma część ułamkową. Wywołując Decimal.Divide, twoje intargumenty są niejawnie konwertowane na Decimals.

Możesz wymusić niecałkowite dzielenie intargumentów, jawnie rzutując co najmniej jeden z argumentów na typ zmiennoprzecinkowy, np .:

int a = 42;
int b = 23;
double result = (double)a / b;
Konrad Rudolph
źródło
2
Niezła odpowiedź. Próbowałem też Decimal.Divide (a, b), co dało ten sam wynik.
Baxter
6

W pierwszym przypadku wykonujesz dzielenie liczb całkowitych, więc wynik jest obcinany (część dziesiętna jest odcinana) i zwracana jest liczba całkowita.

W drugim przypadku liczby całkowite są najpierw konwertowane na liczby dziesiętne, a wynik jest dziesiętny. W związku z tym nie są one obcięte i uzyskasz prawidłowy wynik.

Andrew Rollings
źródło
4

Następująca linia:

int a = 1, b = 2;
object result = a / b;

... zostanie wykonana przy użyciu arytmetyki całkowitej . Decimal.Dividez drugiej strony przyjmuje dwa parametry tego typu Decimal, więc dzielenie będzie dokonywane na wartościach dziesiętnych, a nie całkowitych. To jest równoważne z tym:

int a = 1, b = 2;
object result = (Decimal)a / (Decimal)b;

Aby to zbadać, możesz dodać następujące linie kodu po każdym z powyższych przykładów:

Console.WriteLine(result.ToString());
Console.WriteLine(result.GetType().ToString());

Wynik w pierwszym przypadku będzie

0
System.Int32

.. aw drugim przypadku:

0,5
System.Decimal
Fredrik Mörk
źródło
2

Uważam, że Decimal.Divide(decimal, decimal)niejawnie konwertuje 2 argumenty int na liczby dziesiętne przed zwróceniem wartości dziesiętnej (precyzyjnej), gdzie jako 4/5 jest traktowane jako dzielenie liczby całkowitej i zwraca 0

Gishu
źródło
1

Chcesz rzucić liczby:

podwójne c = (podwójne) a / (podwójne) b;

Uwaga: Jeśli którykolwiek z argumentów w C # jest podwójnym, używany jest podwójny podział, który powoduje podwójne. Tak więc zadziałałoby również:

podwójne c = (podwójne) a / b;

oto mały program:

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();
        }
Jaydeep Shil
źródło
0

Jeśli szukasz odpowiedzi 0 <a <1, int / int nie wystarczy. int / int wykonuje dzielenie liczb całkowitych. Spróbuj rzutować jedną z int na double wewnątrz operacji.

Brian
źródło
1
Int32 to liczba całkowita ze znakiem, czy chodziło Ci o 0 <odpowiedź <1?
Groo
0

W moim przypadku nic powyżej nie działało.

chcę podzielić 278 przez 575 i pomnożyć przez 100, aby znaleźć procent.

double p = (double)((PeopleCount * 1.0 / AllPeopleCount * 1.0) * 100.0);

%: 48,3478260869565 -> 278/575 ---> 0%: 51,6521739130435 -> 297/575 ---> 0

jeśli pomnożę PeopleCount przez 1,0, otrzymamy ułamek dziesiętny, a dzielenie wyniesie 48,34 ... również pomnóż przez 100,0, a nie 100.

Alp Altunel
źródło
-1

Odpowiedź oznaczona jako taka jest już prawie gotowa, ale myślę, że warto dodać, że istnieje różnica między używaniem liczby podwójnej a dziesiętną.

Nie radziłbym sobie lepiej z wyjaśnianiem pojęć niż Wikipedia, więc podam tylko wskazówki:

arytmetyka zmiennoprzecinkowa

typ danych dziesiętnych

W systemach finansowych często wymagane jest, abyśmy mogli zagwarantować dokładność określonej liczby (o podstawie 10) miejsc po przecinku. Generalnie jest to niemożliwe, jeśli dane wejściowe / źródłowe są w bazie 10, ale wykonujemy arytmetykę w podstawie 2 (ponieważ liczba miejsc dziesiętnych wymaganych do dziesiętnego rozwinięcia liczby zależy od podstawy; jedna trzecia zajmuje nieskończenie wiele miejsc po przecinku miejsc do wyrażenia w podstawie-10 jako 0,333333 ..., ale wystarczy jedno miejsce po przecinku w przypadku podstawy-3: 0,1).

Liczby zmiennoprzecinkowe są szybsze w obsłudze (pod względem czasu procesora; pod względem programowania są równie proste) i preferowane, gdy chcesz zminimalizować błąd zaokrąglania (jak w aplikacjach naukowych).

Dojo
źródło
1
Nic w Twojej odpowiedzi nie służy odpowiedzi na pierwotne pytanie
Lord Wilmore