Możliwa utrata frakcji

119

Wybaczcie, jeśli jest to naiwne pytanie, jednak dzisiaj jestem zagubiony.

Mam proste obliczenie podziału, takie jak:

double returnValue = (myObject.Value / 10);

Wartość to int w obiekcie.

Otrzymuję komunikat z informacją o możliwej utracie frakcji. Jednak gdy zmienię double na int, wiadomość znika.

Jakieś przemyślenia, dlaczego tak się stało?

CodeLikeBeaker
źródło
Dziękuję wszystkim za świetne odpowiedzi. Ma to sens teraz, gdy podczas dzielenia 2 int wartości tracisz przecinek dziesiętny.
CodeLikeBeaker

Odpowiedzi:

168

Kiedy podzielisz dwa int na wartość zmiennoprzecinkową, część ułamkowa zostanie utracona. Jeśli rzucisz jeden z elementów na zmiennoprzecinkowy, nie otrzymasz tego błędu.

Na przykład zamień 10 na 10.0

double returnValue = (myObject.Value / 10.0);
Ólafur Waage
źródło
57

Robisz dzielenie całkowite, jeśli myObject.Valuejest int, ponieważ obie strony/ są typu całkowitego.

Aby wykonać dzielenie zmiennoprzecinkowe, jedna z liczb w wyrażeniu musi być typu zmiennoprzecinkowego. Byłoby to prawdą, gdyby wartość myObject.Value była podwójna lub jedna z następujących:

double returnValue = myObject.Value / 10.0;
double returnValue = myObject.Value / 10d; //"d" is the double suffix
double returnValue = (double)myObject.Value / 10;
double returnValue = myObject.Value / (double)10;
lc.
źródło
7

Liczba całkowita podzielona przez liczbę całkowitą zwróci liczbę całkowitą. Rzuć dowolną wartość na podwójną lub podziel przez 10,0.

Kambium
źródło
7

Zakładając, że myObject.Valuejest to intrównaniemyObject.Value / 10 będzie dzieleniem całkowitoliczbowym, które następnie zostanie rzutowane na podwójną.

Oznacza to, że wartość myObject.Value równa 12 spowoduje, że returnValue stanie się 1, a nie 1,2.

Najpierw musisz rzutować wartości:

double returnValue = (double)(myObject.Value) / 10.0;

Dałoby to poprawną wartość 1.2, przynajmniej tak poprawną, na jaką pozwalają podwójne liczby, biorąc pod uwagę ich ograniczenia, ale jest to omawiane w innym miejscu na SO, prawie bez końca :-).

paxdiablo
źródło
4

Myślę, że skoro myObject jest int, powinieneś

double returnValue=(myObject.Value/10.0); 
segfault
źródło