2011-08-28 9 views
70

To jest podstawowe pytanie, ale nie mogę znaleźć odpowiedzi. Poszukałem arytmetyki zmiennoprzecinkowej i kilku innych tematów, ale wydaje się, że nic nie rozwiązało tego problemu. Jestem pewien, że mam po prostu niewłaściwą terminologię.Podział liczb całkowitych w Javie

Zasadniczo chcę wziąć dwie ilości - uzupełnioną i całkowitą - i podzielić je, aby podać procent (o tym, ile zostało zakończone). Ilości są long s. Oto konfiguracja:

long completed = 25000; 
long total = 50000; 

System.out.println(completed/total); // Prints 0 

Próbowałem realokacja wynik na podwójny - drukuje 0.0. Gdzie się mylę?

Nawiasem mówiąc, następnym krokiem jest pomnożenie tego wyniku przez 100, co, jak zakładam, powinno być łatwe, gdy tylko ta mała przeszkoda zostanie przekroczona.

BTW nie zadanie domowe tutaj po prostu stare numskull-ness (i może za dużo kodowania dzisiaj).

+2

Próbowałeś (podwójne) wypełniony/(podwójne) Całkowity wynik ... i następnie przypisując podwójne? –

+2

wypróbować * 1.0/całkowita – user12384512

Odpowiedz

106

Konwersja wyjścia jest za późno; obliczenia zostały już przeprowadzone w arytmetyce całkowitej. Trzeba konwertować te wejścia do double:

System.out.println((double)completed/(double)total); 

pamiętać, że w rzeczywistości nie trzeba konwertować zarówno z nich; tak długo jak jeden jest double, drugi będzie niejawnie konwertowany. Ale wolę robić oba, dla symetrii.

+0

Czy jest jakieś słowo kluczowe w języku Java, aby podzielić dwie liczby, np. ** 'Math.floorDiv (num1, num2)' ** – Rudra

+0

@Rudra - Nie jestem pewien, o co pytasz. Jeśli 'num1' i' num2' są dodatnimi liczbami całkowitymi, wtedy 'num1/num2' daje ci to, co chcesz. W przeciwnym razie jest to po prostu 'Math.floor (num1/num2)'. –

3

Konwersja zarówno completed i total do double lub przynajmniej rzucić im double gdy robi devision. To znaczy. rzuć varaibles, aby podwoić nie tylko wynik.

Ostrożne ostrzeżenie, podczas pracy z float i double jest floating point precision problem.

1

Jeśli nie wykonasz rzutowania jednej z dwóch wartości przed wykonaniem podziału, użyty zostanie podział całkowity (dlatego otrzymujesz 0). Wystarczy jeden z tych dwóch argumentów, aby był wartością zmiennoprzecinkową, tak aby używany był normalny podział (a inna wartość całkowita jest automatycznie przekształcana w zmienną).

prostu spróbuj z

float completed = 50000.0f; 

i będzie dobrze.

9

Do tego nie potrzeba nawet podwójnych. Po prostu pomnóż przez 100 najpierw, a następnie podziel. W przeciwnym razie wynik byłby mniejszy niż 1 i zostałby obcięty do zera, jak zauważyłeś.

edytuj: lub jeśli prawdopodobnie wystąpi przepełnienie, jeśli zostanie przekroczone (tj. Dywidenda jest większa niż 922337203685477581), najpierw podzielić dzielnik przez 100.

+0

Po prostu, aby było jasne: czy wynik będzie * zaokrąglony * lub * wypukły * do zera? Duża różnica. – klaar

0
In Java 
Integer/Integer = Integer 
Integer/Double = Double//Either of numerator or denominator must be floating point number 
1/10 = 0 
1.0/10 = 0.1 
1/10.0 = 0.1 

Po prostu wpisz jeden z nich.

0

Jak wyjaśniono w JLS, operacje na liczbach całkowitych są dość proste.

Jeżeli operator całkowitą inną niż przesunięcia bitowego zawiera co najmniej jeden argument operacji typu długi, to operację prowadzi się przy użyciu 64-bitowego precyzji, a wynik operatora numerycznych typu długości. Jeśli drugi operand nie jest długi, to najpierw rozszerza się (§5.1.5), aby pisać długo po numerycznej promocji (§ 5.6).

W przeciwnym razie operacja jest wykonywana z użyciem 32-bitowej precyzji, a wynikiem operatora numerycznego jest typ int. Jeśli któryś z argumentów nie jest int, to najpierw rozszerza się na typ int przez numeryczną promocję.

Więc aby to krótkie, operacja będzie zawsze powodować int przy tym tylko wyjątkiem, że istnieje wartość w nim long.

int = int + int 
long = int + long 
int = short + short 

Uwaga że priorytetem operatora jest ważna, więc jeśli masz

long = int * int + long 

operacja int * int skutkowałaby int byłoby promować w long podczas operacji int + long

-3

Jako że wynik wyjściowy jest podwójny, należy rzucić albo zakończoną zmienną albo zmienną całkowitą albo obie, aby podwoić podczas dzielenia.

więc prawidłowa implmentation będą:

System.out.println((double)completed/total); 
+2

Tak, tak brzmi przyjęta odpowiedź, sześć lat temu. –