Nauczyłem się PHP, Java i C. Teraz jestem ciekawy, dlaczego istnieje tak wiele rodzajów liczbowych typów danych, takich jak bit, int, float, double i long. Dlaczego nie zrobić tylko jednego typu dla liczb?
Czy ma to jakąś korzyść? Może jeśli użyjemy liczb całkowitych do przechowywania tak małych liczb, możemy zaoszczędzić pamięć?
Odpowiedzi:
Istnieją dwa powody, dla których powinieneś zwracać uwagę na różne typy danych liczbowych.
1. Oszczędzanie pamięci
Po co używać długiej, gdy równie łatwo może być liczbą całkowitą, a nawet bajtem? W ten sposób można zaoszczędzić kilka bajtów pamięci.
2. Liczby zmiennoprzecinkowe i liczby całkowite są przechowywane w komputerze inaczej
Załóżmy, że mamy liczbę 22 zapisaną w liczbie całkowitej. Komputer przechowuje ten numer w pamięci binarnie jako:
Jeśli nie znasz systemu liczb binarnych, można to przedstawić w notacji naukowej jako: 2 ^ 0 * 0 + 2 ^ 1 * 1 + 2 ^ 2 * 1 + 2 ^ 3 * 0 + 2 ^ 4 * 1 + 2 ^ 5 * 0 + ... + 2 ^ 30 * 0. Ostatni bit może, ale nie musi być użyty do wskazania, czy liczba jest ujemna (w zależności od tego, czy typ danych jest podpisany czy niepodpisany).
Zasadniczo jest to suma wartości 2 ^ (bit place) *.
Zmienia się to w przypadku wartości z przecinkiem dziesiętnym. Załóżmy, że masz liczbę 3,75 po przecinku. Jest to określane binarnie jako 11.11. Możemy to przedstawić jako notację naukową jako 2 ^ 1 * 1 + 2 ^ 0 * 1 + 2 ^ -1 * 1 + 2 ^ -2 * 1 lub, znormalizowany, jako 1.111 * 2 ^ 2
Komputer nie może tego jednak zapisać: nie ma wyraźnej metody wyrażenia tego punktu binarnego (wersja dziesiętna w systemie liczb binarnych). Komputer może przechowywać tylko 1 i 0. W tym miejscu pojawia się zmiennoprzecinkowy typ danych.
Zakładając, że sizeof (liczba zmiennoprzecinkowa) wynosi 4 bajty, wtedy w sumie masz 32 bity. Pierwszy bit ma przypisany „bit znaku”. Nie ma pływających lub podwójnych niepodpisanych. Kolejnych 8 bitów jest używanych jako „wykładnik”, a ostatnie 23 bity są używane jako „znaczący” (lub czasami określany jako mantysa). Na przykładzie 3,75 nasz wykładnik wyniósłby 2 ^ 1, a nasze znaczenie wyniósłoby 1,111.
Jeśli pierwszy bit to 1, liczba jest ujemna. Jeśli nie, pozytywne. Wykładnik jest modyfikowany przez coś, co nazywa się „odchyleniem”, więc nie możemy po prostu zapisać „0000 0010” jako wykładnika. Odchylenie dla liczby zmiennoprzecinkowej pojedynczej precyzji wynosi 127, a odchylenie dla podwójnej precyzji (tutaj nazwa podwójnego typu danych ma swoją nazwę) wynosi 1023. 23 ostatnie bity są zarezerwowane dla znaczenia. Znaczenie to po prostu wartości PRAWO naszego punktu binarnego.
Naszym wykładnikiem będzie odchylenie (127) + wykładnik (1) lub przedstawione w postaci binarnej
Nasze znaczenie to:
Dlatego 3,75 jest reprezentowane jako:
Teraz spójrzmy na liczbę 8 reprezentowaną jako liczba zmiennoprzecinkowa i jako liczba całkowita:
Jak na świecie komputer doda 8,0 i 8? Lub nawet pomnóż je !? Komputer (a dokładniej komputery x86) ma różne części procesora, które dodają liczby zmiennoprzecinkowe i liczby całkowite.
źródło
Wcześniej, zanim mieliśmy systemy gigabajtowe (lub na nowoczesnych systemach wbudowanych, takich jak Arduino), pamięć była na wagę złota, dlatego wdrożono skrócone metody określania, ile pamięci zajmie określona liczba - BIT jest prosty - początkowo zajmowałby tylko 1 bit pamięciowy.
Inne rozmiary danych i nazwy różnią się w zależności od systemu. W systemie 32-bitowym INT (lub MEDIUMINT) będzie na ogół 2 bajty, LONGINT będzie 4 bajty, a SMALLINT będzie jednym bajtem. Systemy 64-bitowe mogą mieć LONGINT ustawiony na 8 bajtów.
Nawet teraz - szczególnie w aplikacjach baz danych lub programach, które mają wiele instancji uruchomionych na serwerach (takich jak skrypty po stronie serwera na stronach internetowych) - powinieneś uważać na to, co wybierzesz. Wybranie liczby całkowitej o szerokości 2, 4 lub 8 bajtów do przechowywania wartości od 0 do 100 (które mogą zmieścić się w jednym bajcie) jest niezwykle marnotrawstwem, jeśli masz tabelę bazy danych z milionami rekordów.
Więcej informacji: https://en.wikipedia.org/wiki/Integer_(computer_science)
źródło
Oprócz doskonałych argumentów cpmjr123 na temat niedoboru pamięci oraz kompromisów w zakresie precyzji i zasięgu, terapia może potencjalnie również kompromis w zakresie procesora.
Większość nowoczesnych maszyn ma specjalny sprzęt do wykonywania operacji zmiennoprzecinkowych zwany FPU. Istnieją również systemy, które nie mają FPU (obecnie są to zazwyczaj małe urządzenia osadzone), w związku z czym, w zależności od docelowego sprzętu, albo nie musiałbyś wcale używać typów zmiennoprzecinkowych, albo używać programowej biblioteki zmiennoprzecinkowej. Nawet jeśli twoja maszyna ma FPU, historycznie istniały różnice w zakresie funkcji, które mogła ona zapewnić. Wszelkie funkcje niewykonane sprzętowo musiałyby być wykonane programowo (lub pominięte)
Wykonywanie obliczeń zmiennoprzecinkowych w oprogramowaniu polega na wykonywaniu wielu prostszych operacji obsługiwanych przez sprzęt. W ten sposób zyskujesz również potencjalną kompromis prędkości.
źródło
Być może najważniejsze jest to, że tak naprawdę istnieją trzy różne podstawowe typy liczb.
liczba całkowita, stała liczba dziesiętna i zmiennoprzecinkowa.
Wszystkie zachowują się inaczej.
Prosta operacja, taka jak 7/2, może dać odpowiedzi 3, 3,50 i 3,499 w zależności od zastosowanego typu danych.
„fixed decimal” to typ Kopciuszka, jest obsługiwany natywnie w kilku językach, takich jak COBOL i VisualBasic. Nie ma większego zainteresowania dla informatyków, ale jest niezbędny dla każdego, kto przesyła zestaw kont lub oblicza podatek od sprzedaży na fakturze.
źródło
int
,float
iunsigned int
, odpowiednio. Typy punktów stałych są podkategorią typów dyskretnych, ale pierścienie algebraiczne zasadniczo różnią się od liczb [zamieszanie dotyczące niepodpisanych typów w C wynika z faktu, że w większości zachowują się one jak pierścienie, a nie liczby, ale nie są całkiem spójne] .Oczywiście. Są korzyści. W świecie komputerów pamięć jest jedną z najważniejszych rzeczy do rozważenia. Jaki jest pożytek z posiadania pamięci 2kb, gdy dane mieszczą się w mniej niż 1kb? . Powinny istnieć optymalizacje. Jeśli użyjesz więcej pamięci, to oczywiście zabija prędkość twojego komputera. Czy naprawdę to lubisz? Bez prawa...?
Nie tylko pamięć, ale także organizacja typu liczb. dla instancji zmiennoprzecinkowej. Precyzja ma duże znaczenie i oczywiście powinniśmy mieć jeden typ, który może dać nam większą precyzję.
Jeśli weźmiemy pod uwagę dawne czasy, mieliśmy mniej pamięci, jak zapewne wiesz. Aby go zapisać i mądrze z niego korzystać, mieliśmy te różnice. I wiele więcej, jeśli po prostu spróbujesz przeszukać google. Mam nadzieję, że to pomoże.
źródło
liczby całkowite i liczby rzeczywiste (zmiennoprzecinkowe, podwójne) są koncepcyjnie różnymi typami o różnych zestawach operacji i właściwościach wewnętrznych.
Liczby całkowite są policzalne, ale zmienne nie są itp.
W rzeczywistości liczba zmiennoprzecinkowa / liczba podwójna to struktura, która łączy dwa pola liczb całkowitych: mantysę i wykładnik potęgi. Liczby zespolone (które zostały wyłączone z analizy) są jeszcze bardziej, cóż, złożone.
Każdy praktyczny język powinien mieć co najmniej liczby całkowite i zmiennoprzecinkowe jako odrębne typy - zbyt różne operacje na nich.
źródło
a
(część rzeczywista) ib
(część urojona). Procesor zwykle nie implementuje natywnej obsługi operacji na liczbach zespolonych, chociaż procesor może implementować przyspieszone instrukcje wielokrotnego dodawania operacji na parach wartości, takich jak (a b + c d) i (a b-c d).uint16_t
ma wartość 65535, zwiększenie jej spowoduje, że będzie mieć wartość 0). Idealnie byłoby, gdyby języki miały czysto oddzielne typy reprezentujące zawijanie pierścieni algebraicznych i liczb (pozwalając na przechwytywanie liczb, które są przepełnione, a jednocześnie umożliwiając kodowi łatwe wykonywanie operacji na rzeczach, które powinny się zawijać).Oprócz tego, że typy zmiennoprzecinkowe zachowują się zupełnie inaczej niż typy całkowite, chcę podać bardziej ekstremalny przykład, dlaczego rozmiar na liczbę naprawdę ma znaczenie.
Wyobraź sobie, że chcesz posortować (długą) tablicę. Na przykład w C:
Mamy tutaj 100 milionów liczb.
Jeśli każda liczba ma tylko jeden bajt (więc używaj
unsigned char
zamiastint
), to potrzebuje 100 milionów bajtów miejsca.Jeśli użyjesz
double
, to zwykle jest to 8 bajtów na liczbę, czyli 800 milionów bajtów miejsca.Dlatego za każdym razem, gdy operujesz wieloma obiektami (liczbami w tym przykładzie), rozmiar na obiekt (rozmiar na liczbę w tym przykładzie) naprawdę ma znaczenie.
źródło