Pracując w środowisku Java i C #, nauczyłem się używać int
(32 bity) za każdym razem, gdy potrzebują liczby całkowitej i double
(64 bity) w przypadku wartości ułamkowych. Większość metod z odpowiednich frameworków (JVM i .NET) zwykle oczekuje tych dwóch typów.
Moje pytanie brzmi: dlaczego nie używamy zarówno long
, jak i double
dla spójności? Wiem, że posiadanie 64-bitowej precyzji w liczbach całkowitych nie jest potrzebne przez większość czasu, ale z drugiej strony zazwyczaj nie potrzebujemy 64 bitów precyzji w liczbach zmiennoprzecinkowych, czy też tak?
Co to jest uzasadnienie tego, jeśli w ogóle?
Komentarze
A nswer
Zakres a dokładność
Jedna rzecz jest taka, że podważałbym pomysł, że najbardziej powszechna liczba zmiennoprzecinkowa używa 64-bitowej reprezentacji DPFP (podwójnej precyzji zmiennoprzecinkowej).
Przynajmniej w krytycznych dla wydajności rzeczywistych pola czasu, takie jak gry, SPFP (zmiennoprzecinkowe pojedynczej precyzji) jest nadal znacznie bardziej powszechne, ponieważ przybliżenie i prędkość są lepsze niż najwyższa dokładność.
Być może jednym ze sposobów spojrzenia na to jest to, że 32 -bit int
reprezentuje zakres 2^32
liczb całkowitych (~ 4,3 miliarda). Najczęstszym zastosowaniem liczb całkowitych będzie prawdopodobnie indeksowanie elementów, a to „całkiem zdrowy zakres elementów, który byłby trudny do przekroczenia bez przekraczania pamięci dostępnej w dzisiejszym sprzęcie *.
* Pamiętaj, że podczas przydzielania / uzyskiwania dostępu do pojedynczego, ciągłego bloku 4 gigabajtów, nawet przy 30 gigabajtach wolnego miejsca, mogą wystąpić błędy związane z brakiem pamięci, np. z powodu ciągłości wymagania tego bloku.
32-bitowa liczba całkowita nie jest zawsze bardziej wydajna na poziomie instrukcji, ale generalnie wydaje się być bardziej wydajne, gdy jest zagregowane w tablicę, np. ponieważ wymaga połowy pamięci (więcej indeksów, które mogą zmieścić się w jednej linii strony / pamięci podręcznej, np.).
Zauważ również, że jako Lightness Races in Orbit
wskazuje, że z szerszej perspektywy niekoniecznie jest nawet prawdą, że 32-bitowe liczby całkowite są częściej używane. Moja wąska perspektywa pochodzi z dziedziny, w której ints
32-bitowe są często agregowane przez setki tysięcy do milionów jako indeksy do innej struktury – tam zmniejszenie rozmiaru o połowę może pomóc dużo.
Teraz 64-bitowy DPFP może być używany znacznie więcej niż 64-bitowe liczby całkowite w niektórych kontekstach. Tam dodatkowe bity dodają precyzję zamiast zakresu . Wiele aplikacji może wymagać precyzji lub przynajmniej mieć znacznie łatwiejsze programowanie z dostępną dodatkową precyzją. Więc prawdopodobnie dlatego 64-bitowe DPFP mogą występować częściej niż 64-bitowe liczby całkowite w niektórych obszarach i dlaczego int
może nadal być 32-bitowe w wielu scenariuszach, nawet na platformach 64-bitowych.
Komentarze
- I ' d kwestionuję pomysł że najpowszechniejszy typ danych integralnych ma również szerokość 32 bity, przynajmniej w programach napisanych obecnie na standardowym sprzęcie. Platformy 64-bitowe są teraz tak rozpowszechnione.
- @I Ke: Chodzi o to, że podejrzewam, że wiele programów używa po prostu
int
ilong
, nie zwracając uwagi na zakres … i uważam, że takie oprogramowanie używa obecnie głównie 64-bitowych liczb całkowitych w obu przypadkach. - Hmm, mam poprawkę; najwyraźniej
int
jest generalnie nadal 32-bitowy , głównie po to, by uniknąć wprowadzania błędów tylko w tego rodzaju kodzie. Dobrze, że ' nadal maszsize_t
ilong
. - @LightnessRacesinOrbit Ah, widzę, że ' jestem bardzo stronniczy, ponieważ często pracuję w bazach kodu, które agregują liczby całkowite w jakąś strukturę danych z obawą o całkowity rozmiar pamięci. Starałem się, aby moja odpowiedź była tak neutralna, jak to tylko możliwe.
- @I ke: Osobiście dostosowuję również rozmiary do wszystkich moich typów.Ale ty i ja jesteśmy niewątpliwie nienormalni. 🙂
Odpowiedź
Cóż, int i double to rzecz Java. Na przykład w Objective-C i Swift użyłbyś NSInteger lub Int, który jest 32-bitowy na komputerze 32-bitowym i 64-bitowy na komputerze 64-bitowym. Wystarczająco duże, aby policzyć dowolną liczbę elementów, które mogą znajdować się w pamięci. Zdecydowanie przydatne jest używanie tego samego typu prawie wszędzie, chyba że w konkretnej sytuacji potrzebujesz czegoś innego.
Java stara się, aby kod działał tak samo w każdej implementacji, więc uważają, że powinieneś użyć tego samego typu niezależnie od używanej maszyny i że typ powinien mieć taką samą liczbę bitów, niezależnie od maszyna. Objective-C i Swift (a także C, C ++) mają inny punkt widzenia.
Liczby całkowite są najczęściej używane do liczenia rzeczy i zwykle nie ma tak wielu rzeczy do policzenia. Arytmetyka zmiennoprzecinkowa wymaga precyzji, a 32-bitowe liczby zmiennoprzecinkowe często nie zapewniają wystarczającej precyzji. Używanie 64-bitowych podwójnych wszędzie daje szansę walki, aby zawsze mieć wystarczającą precyzję, bez bycia specjalistą w arytmetyce zmiennoprzecinkowej. float nie „t.
Ale jaką spójność dałoby użycie long i double? Liczby całkowite i zmiennoprzecinkowe to nie to samo. Nie ma potrzeby, aby miały stały rozmiar bitu. Używam punktów 2D i prostokąty. Czy więc dla spójności, czy powinny też mieć 64 bity? Punkty mające 32 bity na komponent, a prostokąty 16? Oczywiście, że nie. Spójność nie jest wymagana.
Komentarze
- To bardzo fajna odpowiedź wyjaśniająca stronę JVM polegającą na utrzymywaniu tego samego rozmiaru każdego typu niezależnie od platformy.
Odpowiedź
short, int, single i double mają ten sam rozmiar w java, co w większości popularnych kompilatorów C dla platform 32-bitowych i 64-bitowych oraz C, takich jak java wyraźnie uważa, że int jest głównym typem całkowitoliczbowym, a double jest głównym typem zmiennoprzecinkowym. Myślę, że rozsądne jest stwierdzenie, że Java odziedziczyła tę konwencję po popularnych kompilatorach C.
Liczby całkowite są zwykle używany do c liczenie lub indeksowanie rzeczy. Jest dość rzadkie (choć nie jest to niespotykane), aby policzyć lub zindeksować więcej niż 2 miliardy czegoś. Rzeczywiście, przed C99 trzeba było używać typów specyficznych dla dostawcy, jeśli chciałeś 64-bitowej liczby całkowitej.
Liczby zmiennoprzecinkowe są zwykle używane jako przybliżenie liczb rzeczywistych. Pojedyncza precyzja jest wystarczająco dobra przez większość czasu, ale nietrudno jest znaleźć problemy, w których powoduje ona niedopuszczalną ilość błędów zaokrąglania. Spodziewam się, że zapotrzebowanie ze strony obliczeń naukowych sprawiło, że obsługa zmiennoprzecinkowych podwójnej precyzji stała się wszechobecna na długo przed 64-bitowymi obsługa liczb całkowitych była.
Co mnie zaciekawia, to fakt, że C wydaje się zachęcać do używania podwójnej precyzji, podczas gdy fortran wydaje się zachęcać do użycia pojedynczej precyzji.
BigDecimal
do liczb zmiennoprzecinkowych, ponieważ zaokrąglanie i porównywanie wartości FP jest tak problematyczne.