Komputery 32-bitowe mogą przechowywać tylko liczby całkowite podpisane do 2 31 - 1.
Jest to dlaczego mamy zabraknie adresów IPv4 i weszły w erę 64-bitową.
Jednak liczba 2 31 - 1 (2147483647) nie jest tak duża jak liczba 1000000000000 (1,000,000,000,000), który wydaje mi się być w stanie wyświetlić w porządku bez mojej maszyny upaść.
Czy ktoś może wyjaśnić, dlaczego tak jest?
10^9
bez awarii komputera?” ale raczej „Jak mogę pisać10^(18)
bez awarii mojego mózgu?”Odpowiedzi:
Odpowiadam na twoje pytanie, zadając ci inne:
Jedną ręką prawdopodobnie policzysz do największej możliwej liczby, a następnie, gdy zabraknie Ci palców, przejdziesz do drugiej ręki. Komputery robią to samo, jeśli muszą reprezentować wartość większą niż pojedynczy rejestr może pomieścić, będą używać wielu 32-bitowych bloków do pracy z danymi.
źródło
Masz rację, że 32-bitowa liczba całkowita nie może zawierać wartości większej niż 2 ^ 32-1. Jednak wartość tej 32-bitowej liczby całkowitej i sposób jej wyświetlania na ekranie to dwie zupełnie różne rzeczy. Wydrukowany ciąg „1000000000000” nie jest reprezentowany przez 32-bitową liczbę całkowitą w pamięci.
Dosłowne wyświetlenie liczby „1000000000000” wymaga 13 bajtów pamięci. Każdy bajt może mieć wartość do 255. Żaden z nich nie może pomieścić całej wartości liczbowej, ale interpretowany indywidualnie jako znaki ASCII (na przykład znak „
0
” jest reprezentowany przez wartość dziesiętną 48, wartość binarna00110000
), mogą być razem w formacie, który ma sens dla ciebie, człowieka.Pokrewną koncepcją w programowaniu jest rzutowanie typów , czyli sposób, w jaki komputer interpretuje określony strumień
0
s i1
s. Jak w powyższym przykładzie, można go interpretować jako wartość liczbową, znak, a nawet coś zupełnie innego. Podczas gdy 32-bitowa liczba całkowita może nie być w stanie pomieścić wartości 1000000000000, 32-bitowa liczba zmiennoprzecinkowa będzie w stanie to zrobić, przy użyciu zupełnie innej interpretacji.Jeśli chodzi o sposób, w jaki komputery mogą pracować i przetwarzać duże liczby wewnętrznie, istnieją 64-bitowe liczby całkowite (które mogą pomieścić wartości do 16 miliardów miliardów), wartości zmiennoprzecinkowe, a także wyspecjalizowane biblioteki, które mogą pracować z dowolnie dużymi liczbami liczby.
źródło
1000000000000
dokładnie. Jest to 10 ^ 12 lub 2 ^ 12 * 5 ^ 12; 5 ^ 12 wymaga 28 bitów mantysy.Przede wszystkim komputery 32-bitowe mogą przechowywać liczby do 2³²-1 w jednym słowie maszynowym . Słowo maszynowe to ilość danych, które procesor może przetwarzać w naturalny sposób (tj. Operacje na danych tej wielkości są realizowane sprzętowo i generalnie są najszybsze do wykonania). Procesory 32-bitowe używają słów składających się z 32 bitów, dzięki czemu mogą przechowywać liczby od 0 do 2³²-1 w jednym słowie .
Po drugie, 1 bilion i 1000000000000 to dwie różne rzeczy.
Naciskając 1raz, a następnie 012 razy wpisujesz tekst. 1wejścia
1
, 0wejścia0
. Widzieć? Wpisujesz postacie. Znaki nie są liczbami. Maszyny do pisania w ogóle nie miały procesora ani pamięci i całkiem dobrze radziły sobie z takimi „liczbami”, ponieważ to tylko tekst.Dowód, że 1000000000000 nie jest liczbą, ale tekstem: może oznaczać 1 bilion (dziesiętny), 4096 (dwójkowo) lub 281474976710656 (szesnastkowo). Ma jeszcze więcej znaczeń w różnych systemach. Znaczenie 1000000000000 to liczba, a przechowywanie jej jest inną historią (za chwilę do niej wrócimy).
Do przechowywania tekstu (w programowaniu nazywa się go ciągiem ) 1000000000000 potrzebujesz 14 bajtów (po jednym dla każdego znaku plus kończący bajt NULL, co w zasadzie oznacza „łańcuch kończy się tutaj”). To 4 słowa maszynowe. 3 i połowa wystarczyłoby, ale jak powiedziałem, operacje na słowach maszynowych są najszybsze. Załóżmy, że ASCII służy do przechowywania tekstu, więc w pamięci będzie wyglądać następująco: (konwersja kodów ASCII odpowiadających
0
i1
na binarne, każde słowo w osobnej linii)Cztery znaki mieszczą się w jednym słowie, reszta zostaje przeniesiona do następnego. Reszta jest przenoszona do następnego słowa, dopóki wszystko (łącznie z pierwszym bajtem NULL) nie pasuje.
Teraz wróć do przechowywania liczb. Działa tak, jak w przypadku przepełnionego tekstu, ale są one dopasowywane od prawej do lewej. To może wydawać się skomplikowane, więc oto przykład. Dla uproszczenia załóżmy, że:
0..9
Oto pusta pamięć na 2 słowa:
Zapiszmy liczbę 4:
Dodajmy teraz 9:
Zauważ, że oba operandy zmieściłyby się w jednym bajcie, ale nie wynik. Ale mamy inny gotowy do użycia. Teraz zapiszmy 99:
Ponownie użyliśmy drugiego bajtu do przechowywania numeru. Dodajmy 1:
Ups ... To się nazywa przepełnienie liczb całkowitych i jest przyczyną wielu poważnych problemów, czasem bardzo kosztownych .
Ale jeśli spodziewamy się, że nastąpi przepełnienie, możemy to zrobić:
A teraz dodaj 1:
Stanie się jaśniejszy, jeśli usuniesz spacje oddzielające bajty i znaki nowej linii:
Przewidywaliśmy, że może dojść do przepełnienia i potrzebujemy dodatkowej pamięci. Obsługa liczb w ten sposób nie jest tak szybka jak w przypadku liczb, które pasują do pojedynczych słów i należy ją zaimplementować w oprogramowaniu. Dodanie obsługi dwóch 32-bitowych słów-słów do 32-bitowego procesora skutecznie czyni z niego 64-bitowy procesor (teraz może on działać na liczbach 64-bitowych natywnie, prawda?).
Wszystko, co opisałem powyżej, dotyczy również pamięci binarnej z 8-bitowymi bajtami i 4-bajtowymi słowami, działa prawie tak samo:
Konwersja takich liczb na system dziesiętny jest jednak trudna. (ale działa całkiem dobrze w systemie szesnastkowym )
źródło
large as the number 1 trillion (1000000000000)
. Poza tym prawie mówisz o arytmetyce z precyzją arbitrażową , ale tak naprawdę nigdy nie wspominasz o żadnym z terminów tego, co mówisz ...Możesz także napisać „TA OŚWIADCZENIE JEST FAŁSZ” bez awarii komputera :) Odpowiedź Scott jest trafna w niektórych ramach obliczeniowych, ale twoje pytanie „pisania” dużej liczby oznacza, że jest to zwykły tekst, przynajmniej do jest interpretowane.
Edycja: teraz z
mniejszym sarkazmembardziej przydatne informacje na temat różnych sposobów przechowywania liczby w pamięci. Opiszę je z większą abstrakcją, tj. W kategoriach, że współczesny programista może pisać kod, zanim zostanie przetłumaczony na kod maszynowy w celu wykonania.Dane na komputerze muszą być ograniczone do określonego typu , a komputerowa definicja tego typu opisuje, jakie operacje można wykonać na tych danych i jak (tj. Porównywać liczby, łączyć tekst lub XOR wartość logiczną). Nie można po prostu dodać tekstu do liczby, podobnie jak nie można pomnożyć liczby przez tekst, aby niektóre z tych wartości można było konwertować między typami.
Zacznijmy od liczb całkowitych bez znaku . W tych typach wartości wszystkie bity służą do przechowywania informacji o cyfrach; twoja jest przykładem 32-bitowej liczby całkowitej bez znaku, w której można zapisać dowolną wartość od
0
do2^32-1
. I tak, w zależności od języka lub architektury używanej platformy, możesz mieć 16-bitowe liczby całkowite lub 256-bitowe liczby całkowite.Co jeśli chcesz uzyskać wynik negatywny? Intuicyjnie podpisane liczby całkowite to nazwa gry. Konwencja polega na przydzielaniu wszystkich wartości od
-2^(n-1)
do2^(n-1)-1
- w ten sposób unikamy nieporozumień związanych z dwoma sposobami pisania+0
i pisania-0
. Tak więc 32-bitowa liczba całkowita ze znakiem zawierałaby wartość od-2147483648
do2147483647
. Zgrabnie, prawda?Ok, omówiliśmy liczby całkowite, które są liczbami bez składnika dziesiętnego. Wyrażenie tego jest trudniejsze: część niecałkowita może sensownie znajdować się gdzieś pomiędzy
0
i1
, więc każdy dodatkowy fragment użyty do jej opisania zwiększyłby jej precyzję: 1/2, 1/4, 1/8 ... Problem w tym, że nie potrafią precyzyjnie wyrazić zwykłego dziesiętnego0.1
jako sumy ułamków, które mogą mieć w mianowniku tylko potęgę dwóch! Czy nie byłoby o wiele łatwiej przechowywać liczbę jako liczbę całkowitą, ale zgodziłeś się zamiast tego wstawić kropkę (dziesiętną)? Nazywa się to stałymi punktami , w których przechowujemy,1234100
ale zgadzamy się na konwencję, by1234.100
zamiast tego odczytać .Stosunkowo częstszym typem wykorzystywanym do obliczeń jest
floating point
. Sposób, w jaki działa, jest naprawdę schludny, używa jednego bitu do przechowywania wartości znaku, a następnie jednego do przechowywania wykładnika i znaczenia. Istnieją standardy, które definiują takie przydziały, ale dla liczby 32-bitowej liczba maksymalna, którą można przechowywać, jest przytłaczającaJest to jednak kosztem precyzji. JavaScript dostępny w przeglądarkach używa 64-bitowych liczb zmiennoprzecinkowych i nadal nie może działać poprawnie. Po prostu skopiuj to do paska adresu i naciśnij enter. Alert spoilera: wynik nie będzie
0.3
.Istnieje więcej alternatywnych typów, takich jak Microsoft .NET 4.5
BigInteger
, które teoretycznie nie mają górnej ani dolnej granicy i muszą być obliczane w „partiach”; ale być może bardziej fascynujące technologie to te, które rozumieją matematykę, takie jak silnik Wolfram Mathematica, który może precyzyjnie pracować z abstrakcyjnymi wartościami, takimi jak nieskończoność .źródło
Kluczem jest zrozumienie, w jaki sposób komputery kodują liczby.
To prawda, że jeśli komputer nalega na przechowywanie liczb za pomocą prostej binarnej reprezentacji liczby za pomocą jednego słowa (4 bajty w systemie 32-bitowym), wówczas komputer 32-bitowy może przechowywać tylko liczby do 2 ^ 32. Ale istnieje wiele innych sposobów kodowania liczb w zależności od tego, co chcesz z nimi osiągnąć.
Jednym z przykładów jest to, jak komputery przechowują liczby zmiennoprzecinkowe. Komputery mogą korzystać z wielu różnych sposobów ich kodowania. Standard IEEE 754 określa zasady kodowania liczb większych niż 2 ^ 32. Zasadniczo komputery mogą to zaimplementować, dzieląc 32 bity na różne części reprezentujące niektóre cyfry liczby i inne bity reprezentujące rozmiar liczby (tj. Wykładnik, 10 ^ x). Pozwala to na znacznie większy zasięgliczb pod względem wielkości, ale zmniejsza dokładność (co jest odpowiednie dla wielu celów). Oczywiście komputer może również użyć więcej niż jednego słowa do tego kodowania, zwiększając precyzję wielkości dostępnych zakodowanych liczb. Prosta 32 wersja dziesiętna standardu IEEE dopuszcza liczby o dokładności około 7 cyfr dziesiętnych i wielkości do około 10 ^ 96 wielkości.
Istnieje jednak wiele innych opcji, jeśli potrzebujesz dodatkowej precyzji. Oczywiście możesz używać więcej słów w swoim kodowaniu bez ograniczeń (choć z ograniczeniem wydajności w celu konwersji do i z formatu zakodowanego). Jeśli chcesz odkryć jeden ze sposobów, można to zrobić, istnieje świetny dodatek typu open source dla programu Excel, który wykorzystuje schemat kodowania pozwalający na setki cyfr precyzji w obliczeniach. Dodatek nazywa się Xnumbers i jest dostępny tutaj . Kod jest w języku Visual Basic, który nie jest najszybszy z możliwych, ale ma tę zaletę, że jest łatwy do zrozumienia i modyfikacji. To świetny sposób, aby dowiedzieć się, w jaki sposób komputery osiągają kodowanie dłuższych liczb. Możesz bawić się wynikami w programie Excel bez konieczności instalowania narzędzi programistycznych.
źródło
Wszystko zależy od twojego pytania.
Możesz napisać dowolną liczbę na papierze. Spróbuj zapisać bilion kropek na białej kartce papieru. Jest powolny i nieskuteczny. Właśnie dlatego mamy 10-cyfrowy system reprezentujący te duże liczby. Mamy nawet nazwy dla wielkich liczb, takich jak „milion”, „bilion” i więcej, więc nie mów
one one one one one one one one one one one...
głośno.Procesory 32-bitowe są zaprojektowane tak, aby działały jak najszybciej i wydajnie z blokami pamięci o długości dokładnie 32 cyfr binarnych. Ale my, ludzie, zwykle używamy 10-cyfrowego systemu numerycznego, a komputery, będąc elektronicznymi, używamy 2-cyfrowego systemu ( binarnego ). Liczby 32 i 64 są po prostu potęgami 2. Więc milion i bilion to potęgi 10. Łatwiej jest nam operować tymi liczbami niż na przykład 65536.
Wielkie liczby dzielimy na cyfry, pisząc je na papierze. Komputery dzielą liczby na większą liczbę cyfr. Możemy zapisać dowolną liczbę, a my też komputery, jeśli je zaprojektujemy.
źródło
32-bitowe i 64-bitowe odnoszą się do adresów pamięci. Pamięć komputera jest jak skrytki pocztowe, każda ma inny adres. CPU (Central Processing Unit) wykorzystuje te adresy do adresowania lokalizacji pamięci w pamięci RAM (pamięć o dostępie swobodnym). Gdy procesor mógł obsługiwać tylko adresy 16-bitowe, można było używać tylko 32 MB pamięci RAM (co wtedy wydawało się ogromne). W wersji 32-bitowej osiągnęło 4+ GB (co wtedy wydawało się ogromne). Teraz, gdy mamy 64-bitowe adresy, pamięć RAM przechodzi w terabajty (co wydaje się ogromne).
Jednak program jest w stanie przydzielić wiele bloków pamięci na rzeczy takie jak przechowywanie liczb i tekstu, to zależy od programu i nie jest związane z rozmiarem każdego adresu. Tak więc program może powiedzieć procesorowi, że użyję 10 bloków adresów pamięci, a następnie zapiszę bardzo dużą liczbę lub ciąg 10 liter lub cokolwiek innego.
Uwaga dodatkowa: Adresy pamięci są wskazywane przez „wskaźniki”, więc wartość 32- i 64-bitowa oznacza rozmiar wskaźnika używanego do uzyskania dostępu do pamięci.
źródło
Ponieważ wyświetlanie liczby odbywa się za pomocą pojedynczych znaków, a nie liczb całkowitych. Każda cyfra w liczbie jest reprezentowana osobnym dosłownym znakiem, którego wartość całkowita jest określona przez zastosowane kodowanie, na przykład
'a'
jest reprezentowana przez wartość ascii97
, podczas gdy'1'
jest reprezentowana przez49
. Sprawdź tabelę ascii tutaj .Wyświetlanie zarówno „a”, jak i „1” jest takie samo. Są literałami postaci, a nie liczbami całkowitymi. Każda literał znaku może mieć maksymalną wartość 255 na 32-bitowej platformie, przechowującą wartość w rozmiarze 8-bitowym lub 1-bajtowym (to zależy od platformy, jednak 8-bitowy jest najbardziej powszechnym rozmiarem znaków), dzięki czemu można je grupować i wystawiany. To, ile osobnych znaków mogą wyświetlać, zależy od ilości pamięci RAM. Jeśli masz tylko 1 bajt pamięci RAM, możesz wyświetlić tylko jeden znak, a jeśli masz 1 GB pamięci RAM, możesz wyświetlać dobrze 1024 * 1024 * 1024 znaków (zbyt leniwy, aby wykonać matematykę).
To ograniczenie dotyczy jednak obliczeń, jednak myślę, że interesuje Cię standard IPV4. Chociaż nie jest to całkowicie związane z komputerami
bit-size
, to w jakiś sposób wpłynęło na standardy. Po utworzeniu standardu IPV4 zapisywały wartości ip w 32-bitowych liczbach całkowitych. Teraz, gdy podałeś rozmiar i stał się standardem. Wszystko, co wiemy o Internecie, zależało od tego, a potem zabrakło nam adresów IP do przypisania. Więc jeśli standard IP został zmieniony na 64-bitowy, wszystko przestanie działać, w tym router (zakładam, że jest to poprawne) i inne urządzenia sieciowe. Trzeba więc stworzyć nowy standard, który właśnie zamienił 32-bitową liczbę całkowitą na 128-bitową. I dostosował resztę standardu. Producent sprzętu musi tylko zadeklarować, że obsługuje ten nowy standard i stanie się wirusowy. Chociaż nie jest to takie proste, ale chyba masz rację.Zastrzeżenie: Większość punktów tutaj przytoczonych jest zgodna z moim założeniem. Mogłem pominąć ważne punkty, aby uprościć sprawę. Nie jestem dobry w liczbach, więc musiałem pominąć niektóre cyfry, ale moim celem jest odpowiedzieć na odpowiedź OP dotyczącą tego, dlaczego nie spowoduje awarii komputera.
źródło
1
ma 0x31 w ASCII, a nie 0x1. 1 GB = 1024 ^ 3 B. Wad IPv4 wynaleziony przed wprowadzeniem 32-bitowych procesorów, więc powiedzenie, że adresy były przechowywane w 32-bitowych liczbach całkowitych, jest w sprzeczności z pytaniem OP. I wreszcie IPv6 używa adresów 128-bitowych, a nie 64-bitowych.W procesorach znajdują się „słowa”. Istnieją inne słowa. Kiedy ludzie mówią „procesor 32-bitowy”, mają na myśli głównie „szerokość magistrali pamięci”. Słowo to składa się z różnych „pól”, które odnoszą się do podsystemów komputera odpowiadających transmisji (24 bity) i sterowaniu (inne bity). Mogę się mylić co do dokładnych liczb, upewnij się, że są to instrukcje.
Zupełnie innym aspektem jest obliczanie. Zestawy instrukcji SSE i MMX mogą przechowywać długie liczby całkowite. Maksymalna długość bez utraty wydajności zależy od aktualnej wersji SSE, ale zawsze wynosi około 64 bitów.
Obecne procesory Opteron mogą obsługiwać liczby o szerokości 256 bitów (nie jestem pewien liczby całkowitej, ale na pewno liczba zmiennoprzecinkowa).
Podsumowanie : (1) szerokość magistrali nie jest bezpośrednio powiązana z szerokością obliczeniową, (2) nawet różne słowa (słowo pamięci, słowo rejestru, słowo magistrali itp.) Nie są ze sobą połączone, oprócz tego mają wspólny dzielnik około 8 lub 16 lub 24. Wiele procesorów używało nawet 6-bitowego słowa (ale jego historia).
źródło
Ogólnie rzecz biorąc, celem urządzenia komputerowego jest przyjmowanie, przetwarzanie, przechowywanie i wysyłanie danych. Podstawowym sprzętem jest jedynie maszyna, która pomaga wykonywać te cztery funkcje. Nic nie może zrobić bez oprogramowania.
Oprogramowanie to kod, który mówi maszynie, jak przyjmować dane, jak je przetwarzać, jak je przechowywać i jak udostępniać je innym.
Podstawowy sprzęt zawsze będzie miał ograniczenia. W przypadku maszyny 32-bitowej większość rejestrów przetwarzających dane ma szerokość tylko 32 bitów. Nie oznacza to jednak, że maszyna nie jest w stanie obsłużyć liczb przekraczających 2 ^ 32, oznacza to, że jeśli chcesz poradzić sobie z większymi liczbami, może to potrwać dłużej niż jeden cykl, aby zaakceptować, przetworzyć, zapisać lub wyemituj to.
Oprogramowanie mówi maszynie, jak obchodzić się z liczbami. Jeśli oprogramowanie jest zaprojektowane do obsługi dużych liczb, wysyła do CPU szereg instrukcji, które podpowiadają, jak obsługiwać większe liczby. Na przykład twój numer może być reprezentowany przez dwa 32-bitowe rejestry. Jeśli chcesz dodać 1234 do swojego numeru, oprogramowanie poinformuje CPU, aby najpierw dodał 1,234 do dolnego rejestru, a następnie sprawdź bit przelewu, aby sprawdzić, czy to dodanie spowodowało, że liczba była zbyt duża dla dolnego rejestru. Jeśli tak, to dodaje 1 do górnego rejestru.
W ten sam sposób, w jaki uczą się podstawowe uczniowie dodawania z przenoszeniem, procesor może zostać poproszony o obsługę liczb większych niż może pomieścić w jednym rejestrze. Dotyczy to większości ogólnych operacji matematycznych, dla liczb o dowolnym rozmiarze praktycznym.
źródło
Różnica polega na tym, jak przechowujemy dane w komputerach.
Masz rację, że w przypadku teoretycznej maszyny 8-bitowej jesteśmy w stanie przechowywać tylko 2 ^ 8 wartości w rejestrze pojedynczego procesora lub w adresie pamięci. (Należy pamiętać, że różni się to od „maszyny” do „maszyny” w zależności od zastosowanego procesora, architektury pamięci itp. Ale na razie trzymajmy się hipotetycznej „stereotypowej” maszyny).
W przypadku teoretycznej maszyny 16-bitowej maksymalna wartość w rejestrze / pamięci wynosi 2 ^ 16, w przypadku maszyny 32-bitowej 2 ^ 32 itp.
Przez lata programiści wymyślili wszelkiego rodzaju szykany, aby przechowywać i obsługiwać liczby większe niż te, które można zapisać w rejestrze pojedynczego procesora lub adresie pamięci. Istnieje wiele metod, ale wszystkie wymagają użycia więcej niż jednego adresu rejestru / pamięci do przechowywania wartości większych niż ich „natywna” szerokość rejestru / pamięci.
Wszystkie te metody są korzystne, ponieważ maszyna może przechowywać / przetwarzać wartości większe niż ich natywna pojemność. Minusem jest to, że prawie wszystkie podejścia wymagają wielu instrukcji maszynowych / odczytów / etc. do obsługi tych liczb. W przypadku sporadycznej dużej liczby nie stanowi to problemu. Gdy mamy do czynienia z dużą ilością wielkich liczb (adresów duża pamięć w szczególności) napowietrznej zaangażowanych spowalnia rzeczy w dół.
Stąd ogólne pragnienie, aby rejestry, lokalizacje pamięci i adresy pamięci były „szersze” i szersze, aby obsługiwać duże liczby „natywnie”, aby takie liczby mogły być obsługiwane przy minimalnej liczbie operacji.
Ponieważ rozmiar liczb jest nieskończony, rejestr procesora / rozmiar pamięci / adresowanie zawsze stanowią równowagę między rodzimym rozmiarem liczby a kosztami związanymi z wdrażaniem coraz większych szerokości.
źródło
Komputery 32-bitowe mogą przechowywać liczby do 2 ^ 32 tylko w jednym słowie maszynowym, ale to nie znaczy, że nie mogą obsługiwać większych jednostek danych.
Komputer 32-bitowy oznacza ogólnie, że szyna danych i szyna adresowa mają szerokość 32 bitów, co oznacza, że komputer może obsłużyć 4 GB przestrzeni adresowej pamięci jednocześnie i wysyłać cztery bajty danych jednocześnie przez szynę danych .
To jednak nie ogranicza komputera do obsługi większej ilości danych, musi tylko podzielić dane na cztery bajty, gdy są przesyłane przez magistralę danych.
Zwykły 32-bitowy procesor Intel może wewnętrznie obsługiwać liczby 128-bitowe, co pozwoliłoby na obsługę liczb takich jak 100000000000000000000000000000000000000 bez żadnego problemu.
Możesz obsługiwać znacznie większe liczby niż w komputerze, ale wtedy obliczenia muszą być wykonane przez oprogramowanie, procesor nie ma instrukcji obsługi liczb większych niż 128 bitów. (Może obsłużyć znacznie większą liczbę w postaci liczb zmiennoprzecinkowych, ale wtedy masz tylko 15 cyfr dokładności.)
źródło
Wystarczy dodać notatkę do wielu innych odpowiedzi, ponieważ jest to dość ważny fakt w tym pytaniu, które zostało pominięte.
„32 bity” oznaczają szerokość adresu pamięci. Nie ma to nic wspólnego z rozmiarem rejestru. Wiele procesorów 32-bitowych prawdopodobnie ma rejestry 64 lub nawet 128-bitowe. W szczególności odnosząc się do linii produktów x86, najnowsze procesory konsumenckie, które są 64-bitowe, mają do 256 rejestrów specjalnych.
Ta różnica między szerokością rejestru a szerokością adresu istnieje od czasów starożytnych, kiedy mieliśmy 4-bitowe rejestry i 8-bitowe adresy lub odwrotnie.
Łatwo zauważyć, że przechowywanie dużej liczby nie stanowi problemu bez względu na rozmiar rejestru, jak wyjaśniono w innych odpowiedziach.
Powodem, dla którego rejestry, niezależnie od ich wielkości, mogą dodatkowo obliczać większe liczby, jest to, że zbyt duże obliczenia można podzielić na kilka mniejszych, które pasują do rejestrów (jest to tylko trochę bardziej skomplikowane w rzeczywistości).
źródło
Odpowiedzi już podane są w rzeczywistości całkiem dobre, ale mają tendencję do zajmowania się tą kwestią z różnych stron i tym samym przedstawiają niepełny obraz. Moim zdaniem są też nieco zbyt techniczne.
Tak więc, aby wyjaśnić coś, co zostało zasugerowane, ale nie zostało wyraźnie wyrażone w żadnej z pozostałych odpowiedzi, i które moim zdaniem jest sednem sprawy:
W swoim pytaniu łączysz kilka pojęć , a jedna z nich („32-bitowa”) może faktycznie odnosić się do różnych rzeczy (a różne odpowiedzi przyjęły różne interpretacje). Wszystkie te pojęcia mają coś wspólnego z liczbą bitów (1 i 0) używanych (lub dostępnych) w różnych kontekstach obliczeniowych (co mam na myśli przez to, mam nadzieję, zostaną wyjaśnione w poniższych przykładach), ale poza tym pojęcia nie są ze sobą powiązane .
Wyraźnie:
Pamiętaj, że nie jest to pełna lista interpretacji wyrażenia „32-bitowy”.
Dodatkowy kredyt: aby naprawdę zobaczyć filozoficzne rozróżnienie między liczbami a prymitywnymi kawałkami pamięci komputera, przeczytaj trochę o maszynach Turinga .
źródło
Jeśli napiszesz na przykład 1000000000000 w kalkulatorze, komputer obliczy go jako liczbę typu rzeczywistego z kropką dziesiętną . Wspomniany limit dla 32 bitów dotyka więcej wszystkich liczb całkowitych bez kropki dziesiętnej. Różne typy danych używają różnych metod wprowadzania bitów / bajtów.
Liczby typu całkowitoliczbowego : Ta tabela może pomóc złapać punkt ( http://msdn.microsoft.com/en-us/library/296az74e.aspx ). Dotyka to limitów dla C ++. Na przykład numer typu Int64 ma ograniczenia od -9223372036854775808 do 9223372036854775807.
Liczby typu rzeczywistego : liczby typu rzeczywistego zawierają wartość z liczbą zmiennoprzecinkową i wykładnikiem i można wprowadzić znacznie większe liczby, ale z ograniczoną dokładnością / precyzją. ( http://msdn.microsoft.com/en-us/library/6bs3y5ya.aspx ) Na przykład LDBL (duży podwójny) w C ++ ma maksymalny wykładnik 308, więc możliwe, że możesz wpisać lub otrzymać jako wynik
9.999 x 10^308
, oznacza to, że mieć teoretycznie 308 (+1) cyfr,9
ale tylko 15 najważniejszych cyfr zostanie użytych do jego przedstawienia, reszta zostanie utracona, z powodu ograniczonej precyzji.Ponadto istnieją różne języki programowania i mogą mieć różne implementacje ograniczeń liczbowych. Możesz więc sobie wyobrazić, że wyspecjalizowane aplikacje mogą obsługiwać znacznie większe (i / lub bardziej dokładne / precyzyjne) liczby niż C ++.
źródło
Jeśli chcesz praktycznego przykładu, ile programów w typowym systemie Linux obsługuje przetwarzanie i wysyłanie dużych liczb:
libgmp
- Biblioteka arytmetyczna wielokrotnej precyzji GNU jest najczęściej używaną biblioteką do tego celu w systemach Linux. Prosty przykład pomnożenia 2 ^ 80 przez 1000:Zasadniczo jest to to samo, co użycie zwykłych operatorów + - * /, tylko z biblioteką do dzielenia liczb i przechowywania ich wewnętrznie jako wiele liczb maszynowych (tj. 32-bitowych). Istnieją również funkcje typu scanf () do przetwarzania konwersji tekstu na typy całkowite.
Struktura
mpz_t
jest dokładnie taka jak w przykładzie Scotta Chamberlaina liczenia do 6 za pomocą dwóch rąk. Jest to w zasadzie tablicamp_limb_t
typów maszynowych słów , a gdy liczba jest zbyt duża, aby zmieścić się w maszynowym słowie, GMP używa wielump_limb_t
do przechowywania wysokich / niskich części tej liczby.źródło
W twoim umyśle znasz tylko 10 różnych cyfr. 0 do 9. Wewnętrznie w twoim mózgu jest to z pewnością zakodowane inaczej niż w komputerze.
Komputer używa bitów do kodowania liczb, ale to nie jest ważne. Tak właśnie inżynierowie postanowili zakodować różne rzeczy, ale należy to zignorować. Możesz myśleć o tym, że 32-bitowy komputer ma unikalną reprezentację ponad 4 miliardów różnych wartości, podczas gdy my ludzie mamy unikalną reprezentację 10 różnych wartości.
Ilekroć musimy zrozumieć większą liczbę, używamy systemu. Najważniejsza jest liczba z lewej strony. To jest 10 razy ważniejsze niż następne.
Komputer zdolny do rozróżnienia między czterema miliardami różnych wartości, podobnie będzie musiał uczynić wartość znajdującą się najbardziej na lewo, w zbiorze wartości, cztery miliardy razy ważniejszą niż następna wartość w tym zbiorze. W rzeczywistości komputer w ogóle go nie obchodzi. Nie przypisuje „ważności” liczbom. Programiści muszą stworzyć specjalny kod, aby się tym zająć.
Ilekroć wartość staje się większa niż liczba unikalnych symboli, 9 w ludzkim umyśle, dodajesz jeden do liczby po lewej stronie.
W takim przypadku liczba nadal mieści się w jednym „gnieździe”
Dlatego ludzie zawsze mają problem z brakiem wystarczającej liczby unikalnych symboli. Jeśli komputer nie ma systemu, który sobie z tym poradzi, po prostu napisze 0, zapominając o dodatkowej liczbie. Na szczęście komputery mają w tym przypadku „flagę przepełnienia”.
Być może nauczyłeś się metody w szkole. Algorytm. Algorytm jest dość prosty. Zacznij od dodania dwóch symboli z lewej strony.
Następnie przejdź do następnego miejsca i wykonaj ten sam dodatek.
Ponieważ mieliśmy przepełnienie, oznacza to, że musimy dodać 1 do następnego numeru.
Nie ma już więcej liczb do dodania, więc po prostu tworzymy szczelinę i wstawiamy 1, ponieważ flaga przepełnienia została podniesiona.
Komputer robi to dokładnie w ten sam sposób, z tym wyjątkiem, że ma 2 ^ 32 lub nawet lepiej 2 ^ 64 różnych symboli, a nie tylko 10 takich jak ludzie.
Na poziomie sprzętowym komputer działa na pojedynczych bitach przy użyciu dokładnie tej samej metody. Na szczęście jest to abstrakcja dla programistów. Bity to tylko dwie cyfry, ponieważ łatwo je przedstawić na linii energetycznej. Albo światło jest włączone, albo wyłączone.
Wreszcie komputer może wyświetlić dowolną liczbę jako prostą sekwencję znaków. W tym są najlepsze komputery. Algorytm konwersji między sekwencją znaków a wewnętrzną reprezentacją jest dość złożony.
źródło
Ponieważ nie wyświetlasz liczby (jeśli chodzi o komputer), ale ciąg znaków lub ciąg cyfr. Pewnie, niektóre aplikacje (jak sądzę, kalkulator), które zajmują się liczbami, są w stanie obsłużyć taką liczbę, tak myślę. Nie wiem, jakich trików używają ... Jestem pewien, że pokrywają to inne, bardziej wyszukane odpowiedzi.
źródło
Większość treści tej odpowiedzi pochodziła pierwotnie z tej odpowiedzi (napisanej przed tym innym pytaniem oznaczonym jako duplikat). Omawiam więc używanie wartości 8-bitowych (nawet jeśli to pytanie dotyczyło wartości 32-bitowych), ale jest to w porządku, ponieważ wartości 8-bitowe są łatwiejsze do zrozumienia koncepcyjnego, a te same pojęcia dotyczą większych wartości, takich jak arytmetyka 32-bitowa.
Po dodaniu dwóch liczb, które są 8-bitowe, największa liczba, jaką można uzyskać (0xFF + 0xFF = 1FE). W rzeczywistości, jeśli pomnożymy dwie liczby, które są 8-bitowe, największa liczba, jaką można uzyskać (0xFF * 0xFF = 0xFE01) to nadal 16 bitów, dwa razy 8-bitów.
Teraz możesz założyć, że procesor x-bit może śledzić tylko x-bit. (Na przykład 8-bitowy procesor może śledzić tylko 8 bitów.) To nie jest dokładne. 8-bitowy procesor odbiera dane w 8-bitowych porcjach. (Te „fragmenty” zazwyczaj mają formalny termin: „słowo”. W 8-bitowym procesorze używa się 8-bitowych słów. W 64-bitowym procesorze można użyć 64-bitowych słów.)
Tak więc, gdy podajesz komputerowi 3 bajty:
Bajt nr 1: instrukcja MUL
Bajt nr 2: bajty wyższego rzędu (np. 0xA5)
Bajt nr 3: bajty niższego rzędu (np. 0xCB)
Komputer może wygenerować wynik, który ma więcej niż 8 bitów. Procesor może generować takie wyniki:
0100 0000 0100 0010 xxxx xxxx xxxx xxxx 1101 0111
aka:
0x4082xxxxD7
Teraz pozwól mi zinterpretować, że dla ciebie:
0x oznacza tylko, że następujące cyfry są szesnastkowe.
Omówię chwilę „40” bardziej szczegółowo.
82 jest częścią rejestru „A”, który jest serią 8 bitów.
xx i xx są częścią dwóch innych rejestrów, nazwanych rejestrem „B” i rejestrem „C”. Powodem, dla którego nie wypełniłem tych bitów zerami lub zerami jest to, że instrukcja „DODAJ” (wysłana do procesora) może spowodować, że te bity pozostaną niezmienione przez instrukcję (podczas gdy większość innych bitów, których używam w tym przykładzie, może zmienić się, z wyjątkiem niektórych bitów flagi).
D7 zmieściłoby więcej bitów, zwanych rejestrem „D”.
Rejestr to tylko pamięć. Rejestry są wbudowane w procesory, więc procesor może uzyskiwać dostęp do rejestrów bez konieczności interakcji z pamięcią na karcie pamięci RAM.
Zatem wynik matematyczny 0xA5 razy 0xCB to 0x82D7.
Dlaczego bity zostały podzielone na rejestry A i D zamiast rejestrów A i B lub rejestrów C i D? Cóż, po raz kolejny to przykładowy scenariusz, którego używam, który miał być raczej podobny do prawdziwego języka asemblera (16-bitowy Intel x86, używany przez Intel 8080 i 8088 i wiele nowszych procesorów). Mogą istnieć pewne wspólne reguły, takie jak rejestr „C” zwykle używany jako indeks operacji zliczania (typowy dla pętli) oraz rejestr „B” używany do śledzenia przesunięć, które pomagają określić lokalizacje pamięci. Zatem „A” i „D” mogą być bardziej powszechne w przypadku niektórych typowych funkcji arytmetycznych.
Każda instrukcja CPU powinna zawierać dokumentację, z której mogą korzystać osoby, które programują w asemblerze. Dokumentacja ta powinna określać, z których rejestrów korzysta każda instrukcja. (Tak więc wybór rejestru, którego należy użyć, jest często określany przez projektantów procesora, a nie programistów w języku asemblera. Chociaż istnieje pewna elastyczność.)
Teraz wracając do „40” w powyższym przykładzie: jest to seria bitów, często nazywana „rejestrem flag”. Każdy bit w rejestrze flag ma nazwę. Na przykład istnieje bit „przepełnienia”, który procesor może ustawić, jeśli wynik jest większy niż miejsce, w którym można zapisać jeden bajt wyników. (Do bitu „przepełnienia” często może odnosić się skrócona nazwa „OF”. To duża litera, a nie zero.) Oprogramowanie może sprawdzić wartość tej flagi i zauważyć „problem”. Praca z tym bitem jest często obsługiwana niewidocznie przez języki wyższego poziomu, więc początkujący programiści często nie uczą się, jak wchodzić w interakcje z flagami procesora. Jednak programiści asemblera mogą często uzyskiwać dostęp do niektórych z tych flag w sposób bardzo podobny do innych zmiennych.
Na przykład możesz mieć wiele instrukcji ADD. Jedna instrukcja ADD może przechowywać 16 bitów wyników w rejestrze A i rejestrze D, podczas gdy inna instrukcja może po prostu przechowywać 8 niskich bitów w rejestrze A, zignorować rejestr D i określić bit przepełnienia. Następnie, później (po zapisaniu wyników rejestru A w głównej pamięci RAM), można użyć innej instrukcji ADD, która przechowuje tylko 8 wysokich bitów w rejestrze (ewentualnie rejestr A). To, czy trzeba użyć flagi przepełnienia, może zależy od tego, jakiej instrukcji mnożenia używasz.
(Często występuje też flaga „niedomiaru”, na wypadek, gdyby odjąć za dużo, aby zmieścić się w pożądanym wyniku).
Aby pokazać, jak skomplikowane są sprawy:
Intel 4004 był 4-bitowym procesorem
Intel 8008 był 8-bitowym procesorem. Miał 8-bitowe rejestry o nazwach A, B, C i D.
Intel 8086 był 16-bitowym procesorem. Miał 16-bitowe rejestry o nazwach AX, BX, CX i DX.
Intel 80386 był 32-bitowym procesorem. Miał 32-bitowe rejestry o nazwach EAX, EBX, ECX i EDX.
Procesory Intel x64 mają 64-bitowe rejestry o nazwach RAX, RBX, RCX i RDX. Układy x64 mogą uruchamiać 16-bitowy kod (w niektórych trybach pracy) i mogą interpretować instrukcje 16-bitowe. Robiąc to, bity tworzące rejestr AX są połową bitów tworzących rejestr EAX, które są połową bitów tworzących rejestr RAX. Tak więc za każdym razem, gdy zmieniasz wartość AX, zmieniasz także EAX i RAX, ponieważ te bity używane przez AX są częścią bitów używanych przez RAX. (Jeśli zmienisz EAX o wartość będącą wielokrotnością 65 536, wtedy 16 niskich bitów pozostaje niezmienionych, więc AX nie zmieni się. Jeśli zmienisz EAX o wartość, która nie jest wielokrotnością 65 536, to wpłynie to również na AX .)
Jest więcej flag i rejestrów niż tylko te, o których wspomniałem. Po prostu wybrałem kilka najczęściej używanych, aby zapewnić prosty przykład koncepcyjny.
Teraz, jeśli korzystasz z 8-bitowego procesora, kiedy piszesz do pamięci, możesz napotkać pewne ograniczenia dotyczące możliwości odniesienia się do adresu 8-bitowego, a nie adresu 4-bitowego lub 16-bitowego. Szczegóły różnią się w zależności od procesora, ale jeśli masz takie ograniczenia, procesor może mieć do czynienia z 8-bitowymi słowami, dlatego procesor jest najczęściej nazywany „procesorem 8-bitowym”.
źródło