Dla tego bloku kodu:
int num = 5;
int denom = 7;
double d = num / denom;
wartość d
wynosi 0.0
. Można go zmusić do pracy, przesyłając:
double d = ((double) num) / denom;
Ale czy jest inny sposób na uzyskanie prawidłowego double
wyniku? Nie lubię rzucać prymitywów, którzy wiedzą, co może się zdarzyć.
java
casting
integer-division
orzech włoski
źródło
źródło
Odpowiedzi:
To pozwala uniknąć obsady. Przekonasz się jednak, że konwersje obsady są dobrze zdefiniowane. Nie musisz zgadywać, po prostu sprawdź JLS . int to double jest rozszerzającą konwersją. Od pkt 5.1.2 :
5 można wyrazić dokładnie jako podwójne.
źródło
1.0
nadal zmienia typ wyniku, tylko w inny sposób. „Wydaje mi się nieczytelnym kodem” nie wyjaśnia, w którym scenariuszu (-ach) Twoim zdaniem pomnożenie1.0
jest w rzeczywistości lepsze (lub dlaczego tak może być).(double)num
jakiś sposób się zmieniająnum
. Nie robi - tworzy tymczasowe podwójne dla kontekstu instrukcji.Co jest złego w rzucaniu prymitywów?
Jeśli z jakiegoś powodu nie chcesz castować, możesz to zrobić
źródło
double d = num * 1D / denom;
Dlaczego masz irracjonalny lęk przed rzucaniem prymitywów? Nic złego się stanie, gdy rzucił
int
siędouble
. Jeśli nie masz pewności, jak to działa, poszukaj go w specyfikacji języka Java . Oddająceint
TOdouble
jest poszerzenie prymitywny konwersji .Możesz pozbyć się dodatkowej pary nawiasów, rzucając mianownik zamiast licznika:
źródło
double d = (double) num / denom;
... (OK, ten zależy od pierwszeństwa)Jeśli zmienisz typ zmiennej, musisz pamiętać, aby ponownie podkraść się dwukrotnie, jeśli zmieni się formuła, ponieważ jeśli ta zmienna przestanie być częścią obliczeń, wynik zostanie pomieszany. Przyzwyczajam się do rzucania w obliczeniach i dodam komentarz obok niego.
Pamiętaj, że rzutowanie wyniku tego nie zrobi
źródło
Rzuć jedną z liczb całkowitych / obu liczb całkowitych, aby uzyskać liczbę zmiennoprzecinkową, aby wymusić wykonanie operacji za pomocą matematyki zmiennoprzecinkowej. W przeciwnym razie zawsze preferowana jest matematyka całkowita. Więc:
Pamiętaj, że rzutowanie wyniku tego nie zrobi. Ponieważ pierwszy podział odbywa się zgodnie z regułą pierwszeństwa.
Nie sądzę, że jest jakiś problem z castingiem, o którym myślisz.
źródło
Type Casting to jedyny sposób
Generowanie
double
z dzielenia liczb całkowitych - nie ma innej drogi bez rzutowania (być może nie zrobisz tego wprost, ale tak się stanie).Istnieje kilka sposobów na uzyskanie dokładnej
double
wartości (gdzienum
i gdziedenom
jestint
typ, i oczywiście z rzutowaniem ) -z jawnym rzutowaniem:
double d = (double) num / denom;
double d = ((double) num) / denom;
double d = num / (double) denom;
double d = (double) num / (double) denom;
ale nie
double d = (double) (num / denom);
z niejawnym rzutowaniem:
double d = num * 1.0 / denom;
double d = num / 1d / denom;
double d = ( num + 0.0 ) / denom;
double d = num; d /= denom;
ale nie
double d = num / denom * 1.0;
i nie
double d = 0.0 + ( num / denom );
źródło
użyj czegoś takiego jak:
(1d jest rzutowany na podwójny)
źródło
Możesz rozważyć zawinięcie operacji. Na przykład:
Umożliwia to sprawdzenie (tylko raz), czy obsada działa dokładnie tak, jak chcesz. Ta metoda może również podlegać testom, aby upewnić się, że nadal wykonuje to, co chcesz. Nie ma również znaczenia, jakiej sztuczki użyjesz, aby spowodować podział (możesz użyć jednej z odpowiedzi tutaj), o ile spowoduje to poprawny wynik. Gdziekolwiek musisz podzielić dwie liczby całkowite, możesz teraz zadzwonić
Utils::divide
i zaufać, że zrobi to dobrze.źródło
po prostu użyj tego.
źródło
Najlepszym sposobem na to jest
źródło