Dlaczego najczęściej jest to liczba całkowita 32 bity, a najczęściej liczba zmiennoprzecinkowa 64 bity?

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

  • ” Może się wydawać, że pływak wystarczy na to, czego każdy rozsądnie potrzebowałby, ale to ' nie … Właściwie 64-bitowe dublety z ich 15 cyframi dziesiętnymi nie są ' t wystarczająco dobre dla wielu aplikacji … ” ( Dlaczego potrzebujesz float / double? )
  • Wychodząc z języka C, ' nauczyłem się używać BigDecimal do liczb zmiennoprzecinkowych, ponieważ zaokrąglanie i porównywanie wartości FP jest tak problematyczne.
  • @TMN I ' Nie jestem pewien, czy typ, który wyrzuca przy próbie obliczenia 1/3, jest rozwiązaniem na wszystko .

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 i long, 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 masz size_t i long.
  • @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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *