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.
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.
Odpowiedzi:
int
jest 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
!). Decimal
z kolei ma część ułamkową. Wywołując Decimal.Divide
, twoje int
argumenty są niejawnie konwertowane na Decimal
s.
Możesz wymusić niecałkowite dzielenie int
argumentó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;
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.
Następująca linia:
int a = 1, b = 2;
object result = a / b;
... zostanie wykonana przy użyciu arytmetyki całkowitej . Decimal.Divide
z 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
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();
}
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.
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:
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).