Pisałem ten kod:
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
Wynik to 0. Dlaczego tak jest i jak rozwiązać ten problem?
źródło
Pisałem ten kod:
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
Wynik to 0. Dlaczego tak jest i jak rozwiązać ten problem?
Dwa operandy (1 i 3) są liczbami całkowitymi, dlatego używana jest arytmetyka liczb całkowitych (tutaj dzielenie). Zadeklarowanie zmiennej wynikowej jako podwójnej powoduje po prostu niejawną konwersję po podzieleniu .
Dzielenie przez liczbę całkowitą zwraca oczywiście prawdziwy wynik dzielenia zaokrąglony do zera. Wynik funkcji 0.333...
jest zatem zaokrąglany w dół do 0. (Zwróć uwagę, że procesor w rzeczywistości nie wykonuje żadnego zaokrąglania, ale nadal możesz o tym myśleć w ten sposób).
Zwróć również uwagę, że jeśli oba operandy (liczby) są podane jako zmiennoprzecinkowe; 3.0 i 1.0, a nawet tylko pierwsza , a następnie używana jest arytmetyka zmiennoprzecinkowa, co daje 0.333...
.
int i = .99999999
ustawia int na 0. Dokładniej, pobiera część całkowitą, a resztę odrzuca.DOWN
jest do zera. Zaokrąglanie wFLOOR
kierunku ujemnej nieskończoności.1/3
używa dzielenia liczb całkowitych, ponieważ obie strony są liczbami całkowitymi.Potrzebujesz co najmniej jednego z nich, aby być
float
lubdouble
.Jeśli wpisujesz wartości w kodzie źródłowym, tak jak twoje pytanie, możesz to zrobić
1.0/3
; to1.0
jest podwójne.Jeśli uzyskasz wartości z innego miejsca, możesz użyć ich
(double)
do przekształceniaint
wdouble
.źródło
Jawnie rzuć to jako plik
double
Dzieje się tak, ponieważ Java używa operacji dzielenia liczb całkowitych dla
1
i3
od czasu wprowadzenia ich jako stałych całkowitych.źródło
powinieneś użyć
lub
Dzielenie liczb całkowitych zwraca liczbę całkowitą.
źródło
Ponieważ robisz dzielenie liczb całkowitych.
Jak mówi @Noldorin, jeśli oba operatory są liczbami całkowitymi, używany jest dzielenie liczb całkowitych.
Wynik 0,33333333 nie może być reprezentowany jako liczba całkowita, dlatego do wyniku jest przypisywana tylko część całkowita (0).
Jeśli którykolwiek z operatorów to
double
/float
, to zostanie przeprowadzona arytmetyka zmiennoprzecinkowa. Ale będziesz miał ten sam problem, jeśli to zrobisz:źródło
Ponieważ traktuje 1 i 3 jako liczby całkowite, dlatego zaokrągla wynik w dół do 0, aby był liczbą całkowitą.
Aby uzyskać wynik, którego szukasz, wyraźnie powiedz javie, że liczby są podwojone, w następujący sposób:
źródło
Ustaw 1 jako zmiennoprzecinkowy i zostanie użyty podział zmiennoprzecinkowy
źródło
Konwersja w JAVA jest dość prosta, ale wymaga pewnego zrozumienia. Jak wyjaśniono w JLS dla operacji na liczbach całkowitych :
A przykład to zawsze najlepszy sposób na przetłumaczenie JLS;)
Mały przykład użycia Eclipse, aby pokazać, że nawet dodanie dwóch
short
znaków nie będzie takie łatwe:Będzie to wymagało odlewania z możliwą utratą precyzji.
To samo dotyczy operatorów zmiennoprzecinkowych
Tak więc promocja odbywa się na float w double.
A połączenie wartości całkowitej i zmiennoprzecinkowej daje wartości zmiennoprzecinkowe, jak powiedziano
Dzieje się tak w przypadku operatorów binarnych, ale nie w przypadku „Operatorów przypisania”, takich jak
+=
Aby to udowodnić, wystarczy prosty przykład roboczy
Powodem jest to, że wykonano tutaj niejawne rzutowanie, będzie to wykonane podobnie
źródło
1 i 3 są liczbami całkowitymi, więc Java wykonuje dzielenie liczb całkowitych, którego wynikiem jest 0. Jeśli chcesz zapisać podwójne stałe, musisz napisać
1.0
i3.0
.źródło
Najłatwiejszym rozwiązaniem jest po prostu to zrobić
To, co robi, ponieważ nie wprowadziłeś 1.0 / 3.0, pozwala ręcznie przekonwertować go na typ danych double, ponieważ Java założyła, że jest to dzielenie całkowite, i zrobiłoby to, nawet jeśli oznaczałoby to zawężenie konwersji. Nazywa się to operatorem rzutowania.
źródło
Ja to zrobiłem.
Użyj .0 podczas wykonywania podwójnych obliczeń, inaczej Java założy, że używasz liczb całkowitych. Jeśli Obliczenie wykorzystuje dowolną ilość podwójnych wartości, wynik będzie podwójną wartością. Jeśli wszystkie są liczbami całkowitymi, wynik będzie liczbą całkowitą.
źródło
(1/3) oznacza dzielenie całkowite, dlatego z tego dzielenia nie można uzyskać wartości dziesiętnej. Aby rozwiązać ten problem, użyj:
źródło
Ponieważ zarówno 1, jak i 3 są liczbami całkowitymi, wynik nie jest zaokrąglony, ale jest obcięty. Więc ignorujesz ułamki i bierzesz tylko całość.
Aby tego uniknąć, miej przynajmniej jedną ze swoich liczb 1 lub 3 w postaci dziesiętnej 1.0 i / lub 3.0.
źródło
Wypróbuj to:
źródło
Wykonaj „double g = 1,0 / 3,0;” zamiast.
źródło
Wielu innym nie udało się wskazać prawdziwego problemu:
To z konieczności oznacza, że wyniki zmiennoprzecinkowe, które mogą być wyświetlane jako liczby całkowite, zostaną obcięte (odcięcie części dziesiętnej).
Co to jest rzutowanie (rzutowanie / konwersja typów), o co pytasz?
Zależy to od implementacji języka, ale Wikipedia ma dość wszechstronny pogląd i mówi również o przymusie , który jest kluczową informacją w odpowiedzi na twoje pytanie.
http://en.wikipedia.org/wiki/Type_conversion
źródło
1/2
W języku docelowym (java). Po prostu wywołujesz dzielenie liczb całkowitych, co da wynik w postaci liczby całkowitej. Rzutowanie typów jest spowodowane tylko konwersją w górę zint
na adouble
podczas przypisywania.0.5
. Po prostu w Javie1/2
jest to dzielenie liczb całkowitych, które daje zerową liczbę całkowitą. Możesz przypisać zero do podwójnego, nadal będzie to zero, chociaż0.0
podwójne.