2014-01-07 20:18:51 +0000 2014-01-07 20:18:51 +0000
369
369
Advertisement

Jeśli maszyny 32-bitowe mogą obsługiwać tylko numery do 2^32, dlaczego mogę napisać 10000000000 (bilion) bez awarii mojej maszyny?

Advertisement

Komputery 32-bitowe mogą przechowywać tylko podpisane liczby całkowite do 231 - 1. Dlatego właśnie zabrakło nam adresów IPv4 i weszliśmy w erę 64-bitową.

Jednak liczba 231 - 1 (2,147,483,647) nie jest tak duża jak 1 bilion (1,000,000,000), który wydaje mi się być w stanie wyświetlić dobrze bez awarii mojej maszyny.

Czy ktoś może wyjaśnić dlaczego tak jest?

Advertisement

Odpowiedzi (18)

784
784
784
2014-01-07 20:31:38 +0000

Odpowiadam na Twoje pytanie zadając Ci inną:

Jak policzyć na palcach do 6?

Prawdopodobnie policzysz do największej możliwej liczby jedną ręką, a następnie przejdziesz do drugiej, gdy zabraknie Ci palców. Komputery robią to samo, jeśli muszą reprezentować wartość większą niż pojedynczy rejestr może mieć, użyją wielu 32-bitowych bloków do pracy z danymi.

395
395
395
2014-01-07 20:36:34 +0000

Masz rację, że 32-bitowa liczba całkowita nie może mieć wartości większej niż 2^32-1. Jednak wartość tej 32-bitowej liczby całkowitej i sposób jej wyświetlania na Twoim ekranie to dwie zupełnie różne rzeczy. Drukowany łańcuch “1000000000000” nie jest reprezentowany przez 32-bitową liczbę całkowitą w pamięci.

Aby dosłownie wyświetlić liczbę “1000000000000” potrzeba 13 bajtów pamięci. Każdy pojedynczy bajt może mieć wartość do 255. Żaden z nich nie może pomieścić całej, liczbowej wartości, ale interpretowane indywidualnie jako znaki ASCII (np. znak “0” jest reprezentowany przez wartość dziesiętną 48, wartość binarna 00110000), mogą być one zwinięte razem w format, który ma sens dla Ciebie, człowieka.

  • *

Powiązanym pojęciem w programowaniu jest typecasting, czyli jak komputer będzie interpretował konkretny strumień 0s i 1s. Tak jak w powyższym przykładzie, może być on interpretowany jako wartość liczbowa, znak, a nawet coś zupełnie innego. Podczas gdy 32-bitowa liczba całkowita może nie być w stanie utrzymać wartości 10000000000, 32-bitowa liczba zmiennoprzecinkowa będzie w stanie, używając zupełnie innej interpretacji.

Jeśli chodzi o sposób, w jaki komputery mogą pracować z dużymi liczbami i przetwarzać je wewnętrznie, istnieją 64-bitowe liczby całkowite (które mogą przyjąć wartości do 16 miliardów), wartości zmiennoprzecinkowe, a także wyspecjalizowane biblioteki, które mogą pracować z dowolnie dużymi liczbami.

190
Advertisement
190
190
2014-01-07 21:37:16 +0000

Eerst en vooral kunnen 32-bits computers nummers tot 2³²-1 ** in één enkel machinewoord** opslaan. Machinewoord ](https://en.wikipedia.org/wiki/Machine_word) is de hoeveelheid gegevens die de CPU op een natuurlijke manier kan verwerken (d.w.z. bewerkingen op gegevens van die grootte worden geïmplementeerd in hardware en zijn over het algemeen het snelst uit te voeren). 32-bits CPU’s gebruiken woorden die bestaan uit 32 bits, dus ze kunnen getallen van 0 tot 2³²-1 in één woord opslaan.

Ten tweede, 1 biljoen en 1000000000000 zijn twee verschillende dingen.

  • 1 biljoen is een abstract begrip van getal
  • 1000000000000 is tekst

Door 1 keer te drukken en dan 12 keer op 0 te drukken, typ je tekst. 1 invoer 1, 0 invoer 0. Zie je? Je bent karakters aan het typen. Tekens zijn geen getallen. Schrijfmachines hadden helemaal geen CPU of geheugen en ze gingen vrij goed om met zulke “getallen”, omdat het gewoon tekst is.

Bewijs dat 1000000000000 geen getal is, maar tekst: het kan 1 biljoen (in decimaal), 4096 (in binair) of 281474976710656 (in hexadecimaal) betekenen. Het heeft nog meer betekenissen in verschillende systemen. Betekenis van 1000000000000 is een getal en het opslaan ervan is een ander verhaal (we komen er zo op terug).

Om de tekst op te slaan (in de programmering heet het string) 100000000000000 heb je 14 bytes nodig (één voor elk karakter plus een afsluitende NULL byte die in principe “de string eindigt hier” betekent). Dat zijn 4 machine-woorden. 3 en de helft zou genoeg zijn, maar zoals ik al zei, operaties op machine woorden zijn het snelst. Laten we aannemen dat ASCII wordt gebruikt voor tekstopslag, dus in het geheugen zal het er zo uitzien: (het omzetten van ASCII-codes die overeenkomen met 0 en 1 naar binair, elk woord in een aparte regel)

00110001 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00000000 00000000 00000000

Vier tekens passen in één woord, de rest wordt verplaatst naar het volgende. De rest wordt verplaatst naar het volgende woord totdat alles (inclusief de eerste NULL-byte) past.

Nu, terug naar het opslaan van getallen. Het werkt net als bij overlopende tekst, maar ze passen van rechts naar links. Het klinkt misschien ingewikkeld, dus hier is een voorbeeld. Laten we voor de eenvoud aannemen dat:

  • onze denkbeeldige computer gebruikt decimaal in plaats van binair
  • één byte kan getallen bevatten 0..9
  • één woord bestaat uit twee bytes

Hier is een leeg 2-word geheugen:

0 0
0 0

Laten we het nummer 4 opslaan:

0 4
0 0

Laten we nu 9 toevoegen:

1 3
0 0

Merk op dat beide operanden in één byte zouden passen, maar niet het resultaat. Maar we hebben een andere klaar voor gebruik. Laten we nu 99:

9 9
0 0

opslaan. We hebben opnieuw een tweede byte gebruikt om het nummer op te slaan. Laten we er 1 toevoegen:

0 0
0 0

Whoops… Dat heet integer overflow en is een oorzaak van veel ernstige problemen, soms zeer dure .

Maar als we verwachten dat er overflow zal plaatsvinden, kunnen we dit doen:

0 0
9 9

En voeg nu 1 toe:

0 1
0 0

Het wordt duidelijker als je byte-scheidende ruimtes en nieuwe lijnen verwijdert:

0099 | +1
0100

We hebben voorspeld dat er overflow kan plaatsvinden en dat we misschien extra geheugen nodig hebben. Het omgaan met getallen is op deze manier niet zo snel als met getallen die in enkele woorden passen en het moet in software worden geïmplementeerd. Het toevoegen van ondersteuning voor twee-32-bit-werknummers aan een 32-bit CPU maakt het effectief een 64-bit CPU (nu kan het op 64-bit getallen werken, toch?).

Alles wat ik hierboven heb beschreven is van toepassing op binair geheugen met 8-bit bytes en 4-byte woorden, het werkt ongeveer hetzelfde:

00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 | +1
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000

Het omzetten van zulke getallen naar een decimaal systeem is echter lastig. (maar het werkt werkt vrij goed met hexadecimale )

40
40
40
2014-01-07 23:06:37 +0000

Jesteś w stanie napisać “OŚWIADCZENIE JEST FALSZE” bez awarii komputera :) @Scott’s answer is spot-on for certain calculation frameworks, but your question of “writing” a large number implies that it’s just plain text, at least until it’s interpreted.

Edit: now with less sarcasm~ more useful information on different ways a number can be stored in memory. Opiszę je przy pomocy higher abstraction, czyli w taki sposób, aby nowoczesny programista mógł napisać kod zanim zostanie on przetłumaczony na kod maszynowy do wykonania.

Dane na komputerze muszą być ograniczone do pewnego type, a komputerowa definicja takiego typu opisuje jakie operacje mogą być wykonywane na tych danych i jak (np. porównywanie liczb, konkatenat tekstu czy XOR a boolean). Nie można po prostu dodać tekstu do liczby, tak samo jak nie można pomnożyć liczby przez tekst, więc niektóre z tych wartości mogą być konwertowane pomiędzy typami.

Zacznijmy od nieoznaczonych liczb całkowitych. W tych typach wartości, wszystkie bity są używane do przechowywania informacji o cyfrach; twój jest przykładem 32-bitowej liczby całkowitej niepodpisanej, gdzie każda wartość z 0 do 2^32-1 może być zapisana. 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 ujemny? Intuicyjnie, znakowane liczby całkowite to nazwa gry. Konwencja polega na przypisaniu wszystkich wartości z -2^(n-1) do 2^(n-1)-1 - w ten sposób unikniemy zamieszania związanego z dwoma sposobami zapisu +0 i -0. Tak więc 32-bitowa, podpisana liczba całkowita miałaby wartość od -2147483648 do 2147483647. Zgrabne, nieprawdaż?

Ok, uwzględniliśmy liczby całkowite, które są liczbami bez składnika dziesiętnego. Wyrażanie ich jest o wiele trudniejsze: część niezintegrowana może być sensownie tylko gdzieś pomiędzy 0 a 1, więc każdy dodatkowy bit użyty do jej opisania zwiększyłby jej dokładność: ½, ¼, 1/8… Problem polega na tym, że nie można precyzyjnie wyrazić prostego dziesiętnego 0.1 jako sumy ułamków, które mogą mieć tylko dwie moce w swoim mianowniku! Czy nie byłoby o wiele łatwiej zapisać tę liczbę jako liczbę całkowitą, ale zgodzić się na umieszczenie w niej kropki radix (dziesiętnej)? Nazywa się to ____xed point numbers, gdzie przechowujemy 1234100, ale zgadzamy się na konwencję, aby zamiast tego odczytywać go jako 1234.100.

Stosunkowo bardziej popularnym typem używanym do obliczeń jest floating point. Sposób w jaki to działa jest naprawdę schludny, używa jednego bitu do przechowywania wartości znaku, a kilku do przechowywania wykładnika i znaczenia. Istnieją standardy, które definiują takie alokacje, ale dla 32-bit float maksymalna liczba jaką można by zapisać to przytłaczająca

(2 - 2^-23) * 2^(2^7 - 1) ≈ 3.4 * 10^38

To jednak przychodzi kosztem precyzji. JavaScript dostępny w przeglądarkach używa 64-bitowego float'u, a i tak nie jest w stanie niczego naprawić. Po prostu skopiuj to do paska adresu i wciśnij enter. Alarm spoilera: wynik to nie będzie 0.3.

javascript:alert(0.1+0.2);

Istnieje więcej alternatywnych typów jak Microsoft .NET 4.5’s BigInteger , który teoretycznie nie ma górnej lub dolnej granicy i musi być obliczany w “wsadach”; ale być może bardziej fascynujące są te, które zrozumiały matematykę, jak silnik Wolframa Mathematica, który może precyzyjnie pracować z abstrakcyjnymi wartościami jak nieskończoność .

31
Advertisement
31
31
2014-01-07 21:58:50 +0000

Kluczem jest zrozumienie, jak komputery encode liczb.

Prawda, jeśli komputer nalega na przechowywanie liczb za pomocą prostej binarnej reprezentacji liczby za pomocą jednego słowa (4 bajty w systemie 32-bitowym), to 32-bitowy komputer może przechowywać liczby tylko do 2^32. Ale istnieje wiele innych sposobów kodowania liczb w zależności od tego, co chcesz za ich pomocą osiągnąć.

Jednym z przykładów jest sposób, w jaki komputery przechowują liczby zmiennoprzecinkowe. Komputery mogą używać całej gamy różnych sposobów na ich kodowanie. Standard IEEE 754 definiuje zasady kodowania liczb większych niż 2^32. Rozważnie, komputery mogą to zrealizować dzieląc 32 bity na różne części reprezentujące niektóre cyfry liczby i inne bity reprezentujące size liczby (tj. wykładnik, 10^x). Pozwala to na znacznie większy zakres liczb pod względem rozmiaru, ale kompromituje precyzję (co jest OK dla wielu celów). Oczywiście komputer może również używać więcej niż jednego słowa do tego kodowania, zwiększając precyzję wielkości dostępnych zakodowanych liczb. Prosta, dziesiętna 32 wersja standardu IEEE pozwala na tworzenie liczb z około 7 cyframi dziesiętnymi o dokładności i liczbami o wielkości do około 10^96.

Ale jest wiele innych opcji, jeśli potrzebujesz dodatkowej precyzji. Oczywiście możesz użyć więcej słów w swoim kodowaniu bez ograniczeń (choć z karą za wydajność, aby zamienić na i z zakodowanego formatu). Jeśli chcesz odkryć jeden sposób, w jaki można to zrobić, jest wielki dodatek open-source dla Excela, który wykorzystuje schemat kodowania pozwalający na setki cyfr precyzji w obliczeniach. Dodatek ten nazywa się Xnumbers i jest dostępny tutaj . Kod jest w Visual Basic, który nie jest najszybszy z możliwych, ale ma tę zaletę, że jest łatwy do zrozumienia i modyfikacji. Jest to świetny sposób, aby dowiedzieć się jak komputery osiągają kodowanie dłuższych liczb. I możesz bawić się wynikami w Excelu bez konieczności instalowania jakichkolwiek narzędzi programistycznych.

24
24
24
2014-01-07 23:47:36 +0000

To wszystko jest w twoim pytaniu.

Możesz napisać na papierze dowolny numer. Spróbuj napisać bilion kropek na białej kartce papieru. To jest powolne i nieskuteczne. Dlatego mamy 10-cyfrowy system, który reprezentuje te duże liczby. Mamy nawet nazwy dla dużych liczb, takich jak “milion”, “bilion” i więcej, więc nie mówisz głośno one one one one one one one one one one one....

32-bitowe procesory są zaprojektowane tak, aby pracować najszybciej i najskuteczniej z blokami pamięci, które mają dokładnie 32 cyfry binarne. Ale my, ludzie, powszechnie używamy 10-cyfrowego systemu numerycznego, a komputery, będąc elektroniczne, używają systemu 2-cyfrowego binarnego ). Liczby 32 i 64 to po prostu potęgi 2, tak jak milion i bilion to potęgi 10. Łatwiej jest nam operować tymi liczbami niż np. tłumami 65536.

Wielkie liczby dzielimy na cyfry, gdy piszemy je na papierze. Komputery rozbijają liczby na większą liczbę cyfr. Możemy zapisać dowolną liczbę, a także komputery, jeśli je tak zaprojektujemy.

15
Advertisement
15
15
2014-01-08 00:42:45 +0000

32bit i 64bit odnoszą się do adresów pamięci. Pamięć komputera jest jak skrzynki pocztowe, każda z nich ma inny adres. CPU (Centralna Jednostka Przetwarzająca) używa tych adresów do adresowania lokalizacji pamięci RAM (pamięć Random Access Memory). Kiedy procesor mógł obsługiwać tylko adresy 16-bitowe, Ty mogłeś używać tylko 32mb pamięci RAM (co w tamtych czasach wydawało się ogromne). Z 32bitami poszło to do 4+gb (co w tamtych czasach wydawało się ogromne). Teraz, gdy mamy 64-bitowe adresy, pamięć RAM idzie w terabajty (co wydawało się ogromne). Jednak program jest w stanie przydzielić wiele bloków pamięci na rzeczy takie jak przechowywanie liczb i tekstu, to jest do programu i nie ma związku z wielkością każdego adresu. Tak więc program może powiedzieć CPU, mam zamiar użyć 10 bloków adresowych i następnie zapisać bardzo dużą liczbę, lub łańcuch 10 liter lub cokolwiek. Uwaga boczna: Adresy pamięci są wskazywane przez “wskaźniki”, więc 32- i 64-bitowa wartość oznacza rozmiar wskaźnika używanego do dostępu do pamięci.

13
13
13
2014-01-08 06:44:38 +0000

Ponieważ wyświetlanie liczby odbywa się za pomocą pojedynczych znaków, a nie liczb całkowitych. Każda cyfra w liczbie jest reprezentowana osobnym znakiem dosłownym, którego wartość całkowita jest określona przez stosowane kodowanie, na przykład 'a' jest reprezentowane przez wartość ascii 97, natomiast '1' jest reprezentowane przez 49. Sprawdź tabelę ascii tutaj . Wyświetlanie zarówno ‘a’ jak i ‘1’ jest takie samo. Są to dosłowne znaki, a nie liczby całkowite. Każdy znak dosłowny może mieć maksymalną wartość 255 w 32-bitowej platformie przechowującej wartość w rozmiarze 8 bitów lub 1 bajta (jest to zależne od platformy, jednak 8 bitów jest najczęściej spotykaną wielkością znaków), dzięki czemu mogą być one grupowane i wyświetlane. To, ile oddzielnych znaków mogą one wyświetlać, zależy od posiadanej pamięci RAM. Jeśli masz tylko 1 bajt pamięci RAM, możesz wyświetlić tylko jeden znak, jeśli masz 1GB pamięci RAM, możesz wyświetlić dobrze 1024 *1024 *1024 znaków (Zbyt leniwy, aby zrobić matematykę).

Ograniczenie to dotyczy jednak obliczeń, jednak domyślam się, że jesteś zainteresowany standardem IPV4. Chociaż nie jest on całkowicie związany z komputerem bit-size, w jakiś sposób wpływa na standardy. Podczas tworzenia standardu IPV4, wartości ip były zapisywane w 32-bitowych liczbach całkowitych. Teraz, po podaniu wielkości, stał się on standardem. Od tego zależało wszystko, co wiemy o Internecie, a potem zabrakło nam adresów IP do przypisania. Więc jeśli standard IP został zmieniony na 64-bitowy, wszystko po prostu przestanie działać, w tym Twój router (zakładam, że to jest poprawne) i inne urządzenia sieciowe. Tak więc należy 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 wspiera ten nowy standard i dostanie on wirusy. Choć nie jest to takie proste, ale chyba masz rację.

Zaprzeczenie: Większość z wymienionych tu punktów jest zgodna z moim założeniem. Być może pominąłem tu ważne punkty, żeby to uprościć. Nie jestem dobry w cyfrach, więc musiałem pominąć kilka cyfr, ale chodzi mi o to, aby odpowiedzieć OP na pytanie, dlaczego nie rozbije komputera.

13
Advertisement
13
13
2014-01-08 11:27:08 +0000

W procesorach jest “słowo”. Są inne słowa. Kiedy ludzie mówią “procesor 32-bitowy”, oznaczają one głównie “szerokość szyny pamięci”. Słowo to składa się z różnych “pól”, które odnoszą się do podsystemów komputera odpowiadających za nadawanie (24 bity) i sterowanie (inne bity). Mogę się mylić co do dokładnych liczb, upewnij się o tym w podręcznikach.

Zupełnie inny aspekt to 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 jest to wielokrotność 64 bitów.

Aktualne procesory Opteron potrafią obsłużyć 256 bitowych liczb całkowitych (nie jestem pewien co do liczb całkowitych, ale float jest na pewno).

Summary : (1) szerokość magistrali nie jest podłączona bezpośrednio do szerokości obliczeniowej, (2) nawet różne słowa (słowo pamięci, słowo rejestracji, słowo magistrali itp.) nie są połączone ze sobą, inne mają wspólny dzielnik około 8 lub 16 lub 24. Wiele procesorów użyło nawet 6-bitowego słowa (ale jego historia).

10
10
10
2014-01-08 20:39:13 +0000

Ogólnie rzecz biorąc, celem urządzenia obliczeniowego jest przyjmowanie, przetwarzanie, przechowywanie i emitowanie danych. Podstawowym sprzętem jest jedynie maszyna, która pomaga w wykonywaniu tych czterech funkcji. Nie może wykonać żadnej z tych funkcji bez oprogramowania.

Oprogramowanie to kod, który mówi maszynie, jak akceptować dane, jak je przetwarzać, jak je przechowywać i jak dostarczać je innym.

Podstawowy sprzęt zawsze będzie miał ograniczenia. W przypadku maszyny 32 bitowej, większość rejestrów, które przetwarzają dane ma tylko 32 bity szerokości. Nie oznacza to jednak, że maszyna nie może obsługiwać liczb większych niż 2^32, oznacza to, że jeśli chcesz obsługiwać większe liczby, może potrzebować więcej niż jednego cyklu, aby je zaakceptować, przetworzyć, zapisać lub wyemitować.

Oprogramowanie mówi maszynie, jak obsługiwać liczby. Jeśli oprogramowanie jest zaprojektowane do obsługi dużych liczb, wysyła do procesora szereg instrukcji, które mówią mu, 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ć 1 234 do swojego numeru, program powie CPU, aby najpierw dodał 1 234 do dolnego rejestru, a następnie sprawdzi bit przepełnienia, aby sprawdzić, czy ten dodatek nie spowodował, że numer jest zbyt duży dla dolnego rejestru. Jeśli tak, to dodaje 1 do górnego rejestru.

W ten sam sposób, w jaki uczniowie szkół podstawowych uczą się dodawać z przeniesieniem, CPU może zostać poproszony o obsługę numerów większych niż te, które może trzymać w jednym rejestrze. Jest to prawdziwe dla większości ogólnych operacji matematycznych, dla numerów o dowolnej praktycznej wielkości.

8
Advertisement
8
8
2014-01-09 15:18:54 +0000

Komputery 32-bitowe mog± przechowywać liczby tylko do 2^32 w jednym słowie maszynowym, ale nie oznacza to, że nie mog± obsługiwać większych encji danych.

Znaczenie komputera 32-bitowego jest generalnie takie, że szyna danych i szyna adresowa ma szeroko¶ć 32 bitów, co oznacza, że komputer może obsłużyć 4 GB przestrzeni adresowej pamięci naraz i wysłać cztery bajty danych na raz przez szynę danych.

To jednak nie ogranicza komputera do obsługi większej ilości danych, po prostu musi on podzielić dane na cztery bajtowe fragmenty, gdy jest wysyłany przez magistralę danych.

Zwykły 32-bitowy procesor Intel może obsługiwać wewnętrznie 128-bitowe numery, co pozwoliłoby na bezproblemową obsługę numerów takich jak 1000000000000000000000000000000000000.

Możesz obsłużyć znacznie większe liczby niż w komputerze, ale wtedy obliczenia muszą być wykonane przez oprogramowanie, procesor nie ma instrukcji do obsługi liczb większych niż 128 bitów. (Może obsługiwać znacznie większe liczby w postaci liczb zmiennoprzecinkowych, ale wtedy masz tylko 15 cyfr precyzji).

6
6
6
2014-01-10 19:11:43 +0000

Wystarczy dodać notatkę do wielu innych odpowiedzi, ponieważ jest to dość ważny fakt w tym pytaniu, który został pominięty.

“32 bit” odnosi się do szerokości adresu pamięci. Nie ma to nic wspólnego z wielkością rejestru. Wiele 32-bitowych procesorów prawdopodobnie posiada 64 lub nawet 128-bitowe rejestry. W szczególno¶ci odnosz±c się do linii produktów x86, najnowsze procesory konsumenckie, które wszystkie s± 64-bitowe, posiadaj± do 256 bitowych rejestrów do celów specjalnych.

Ta różnica pomiędzy szeroko¶ci± rejestrów a szeroko¶ci± adresów istnieje od czasów starożytnych, kiedy to posiadali¶my 4-bitowe rejestry i 8-bitowe adresy, lub odwrotnie.

Łatwo zauważyć, że przechowywanie dużej liczby nie jest problemem bez względu na wielkość rejestru, jak to 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 mogą być podzielone na kilka mniejszych, które mieszczą się w rejestrach (w rzeczywistości jest to tylko trochę bardziej skomplikowane).

6
Advertisement
6
6
2014-01-10 21:36:01 +0000

Udzielone już odpowiedzi są właściwie całkiem niezłe, ale mają tendencję do zajmowania się tą kwestią z różnych stron i tym samym przedstawiają niepełny obraz sytuacji. Są też trochę zbyt techniczne, moim zdaniem.

Tak więc, aby wyjaśnić coś, co jest podpowiedziane, ale nie wyrażone wprost w żadnej z pozostałych odpowiedzi, i co moim zdaniem jest sednem sprawy:

Mieszasz kilka pojęć w swoim pytaniu , a jedno z nich (“32 bit”) 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, mam nadzieję, że wyjaśnią to poniższe przykłady), ale pojęcia te są w przeciwnym razie niepowiązane.

Wyraźnie:

  • “IPv4/6” odnosi się do protokół internetowy , zbioru zasad określających sposób pakowania i interpretacji informacji w Internecie. Podstawowym (lub przynajmniej najbardziej znanym) rozróżnieniem pomiędzy IPv4 i IPv6 jest to, że przestrzeń adresowa (tj. zestaw adresów, które można wykorzystać do rozróżnienia różnych lokalizacji w sieci) jest większa w IPv6. Ma to związek z tym, ile bitów w każdym pakiecie danych wysyłanych przez sieć jest przypisanych dla (tzn. odłożonych w celu) identyfikacji nadawcy pakietu i jego docelowego odbiorcy.
  • Analogia niekomputerowa: Każdy pakiet jest jak list wysyłany za pomocą poczty ślimakowej, a przestrzeń adresowa jest jak ilość znaków, które można “użyć” przy zapisywaniu adresu i adresu zwrotnego na kopercie.
  • Nie widzę tego w żadnej z pozostałych odpowiedzi do tej pory.
  • “słowa” pamięci komputera (32-bitowe i 64-bitowe) mogą być generalnie uważane za najmniejszy kawałek danych, które komputer używa, lub “myśli” w. Te bity danych składają się na inne bity danych, takie jak kawałki tekstu lub większe liczby całkowite.
  • Analogia nieobliczeniowa: słowa można myśleć trochę jak litery tworzące słowa na papierze, lub nawet jak pojedyncze słowa w pociągu myślowym.
  • Patrz odpowiedź Guffa , odpowiedź Sanarisa , oraz pierwszy akapit odpowiedź gronostaja .
  • 32-bitowe punkty mogą być słowami, ale mimo to są traktowane atomowo (tzn. jako pojedyncze jednostki, których nie można rozbić na mniejsze składniki). Wskaźniki są najniższym poziomem, w którym komputer może zapisać w pamięci jakiś dowolny fragment danych. Zwróć uwagę, że rozmiar wskaźnika używany przez komputer (a w rzeczywistości przez system operacyjny) ogranicza zakres pamięci, do którego może mieć dostęp pojedynczy wskaźnik, ponieważ istnieje tylko tyle możliwych miejsc pamięci, do których wskaźnik może “wskazywać”, ile jest możliwych wartości dla samego wskaźnika. Jest to analogiczne do sposobu, w jaki IPv4 ogranicza zakres możliwych adresów internetowych, ale nie ogranicza nie ilości danych, które mogą być obecne np. na konkretnej stronie internetowej. Wielkość wskaźnika nie ogranicza jednak nie wielkości samych danych, na które wskaźnik może wskazywać. (Na przykład schemat pozwalający na to, aby rozmiar danych przekraczał zakres wskaźnika, sprawdź linuksową strukturę wskaźnika inode . Zauważ, że jest to nieco inne użycie słowa “wskaźnik” niż typowe, ponieważ wskaźnik zazwyczaj odnosi się do wskaźnika w pamięci dostępowej losowej, a nie do miejsca na dysku twardym.)
  • Analogia nieobliczeniowa: hmmmm…ten jest trochę skomplikowany. Może system dziesiętny Deweya do indeksowania materiałów bibliotecznych jest trochę podobny? Albo jakikolwiek system indeksowania, naprawdę.
  • Patrz odpowiedź SiteNooka .
  • Proszę zauważyć, że moje wyjaśnienie wskaźników powyżej eliduje pewne subtelne szczegóły i prawdopodobnie nie jest całkowicie poprawne. Jednak w językach programowania, w których programiści pracują bezpośrednio ze wskazówkami, tryb mentalny, który narysowałem, jest zazwyczaj wystarczający dla celów praktycznych.
  • Numery, które komputer jest “w stanie wyświetlić ”** nie są (dla celów praktycznych) ograniczone przez sprzęt lub system operacyjny komputera; są one traktowane jak każdy inny tekst.
  • Analogia nieobliczeniowa: pisanie na kartce papieru
  • Patrz odpowiedź użytkownika1306322 i odpowiedź Bigbio2002

Zauważ, że nie jest to w zamierzeniu wyczerpująca lista interpretacji wyrażenia “32 bit.”

Dodatkowa uwaga: aby naprawdę zobaczyć gołe kości filozoficznego rozróżnienia między liczbami a prymitywnymi fragmentami pamięci komputera, przeczytaj trochę o Turingach .

5
5
5
2014-01-11 23:24:10 +0000

W twojej głowie znasz tylko 10 różnych cyfr. Od 0 do 9. Wewnętrznie w twoim mózgu jest to na pewno zakodowane inaczej niż w komputerze.

Komputer używa bitów do kodowania liczb, ale to nie jest ważne. To jest po prostu sposób, w jaki inżynierowie wybrali kodowanie rzeczy, ale należy to zignorować. Można o tym myśleć, ponieważ 32-bitowy komputer ma unikalną reprezentację ponad 4 miliardów różnych wartości, podczas gdy my, ludzie, mamy unikalną reprezentację dla 10 różnych wartości.

Zawsze, gdy musimy zrozumieć większą liczbę, używamy systemu. Najważniejsza jest najbardziej lewicowa liczba. Jest ona 10 razy ważniejsza od następnej.

Komputer, który potrafi rozróżnić cztery miliardy różnych wartości, będzie musiał podobnie uczynić najbardziej lewą wartość, w zbiorze wartości, cztery miliardy razy ważniejszą od następnej wartości w tym zbiorze. W rzeczywistości komputer w ogóle się tym nie przejmuje. Nie przypisuje “znaczenia” liczbom. Programiści muszą zrobić specjalny kod, aby się tym zająć.

Ilekroć wartość staje się większa niż liczba unikalnych symboli, 9 w ludzkim umyśle, dodajemy jeden do liczby po lewej stronie.

3+3=6

W tym przypadku liczba nadal mieści się w jednym “slocie”

5+5=10. This situation is called an overflow.

Tak więc ludzie zawsze mają do czynienia z problemem braku wystarczającej liczby unikalnych symboli. Jeśli komputer nie ma systemu, który by sobie z tym poradził, po prostu napisałby 0, zapominając o tym, że istnieje dodatkowa liczba. Na szczęście, komputery mają “flagę przepełnienia”, która jest w tym przypadku podniesiona.

987+321 is more difficult.

Możesz nauczyć się metody w szkole. Algorytm. Algorytm jest dość prosty. Zacznij od dodania dwóch najbardziej lewych symboli.

7+1=8, we now have ...8 as the result so far

Następnie przejdź do następnego slotu i wykonaj to samo dodanie.

8+2=10, the overflow flag is raised. We now have ...08, plus overflow.

Ponieważ mieliśmy przepełnienie, oznacza to, że musimy dodać 1 do następnej liczby.

9+3=12, and then we add one due to overflow. ...308, and we had another overflow.

Nie ma więcej liczb do dodania, więc po prostu tworzymy slot i wstawiamy 1, ponieważ flaga przepełnienia została podniesiona.

1308

Komputer robi to dokładnie tak samo, z wyjątkiem tego, że ma 2^32 lub nawet lepiej 2^64 różne symbole, zamiast tylko 10 jak ludzie.

Na poziomie sprzętowym, komputer pracuje na pojedynczych bitach, używając dokładnie tej samej metody. Na szczęście jest to abstrakcyjne dla programistów. Bity to tylko dwie cyfry, ponieważ można je łatwo odwzorować w linii zasilającej. Albo światło jest włączone, albo wyłączone.

Na koniec, komputer może wyświetlić dowolną liczbę w postaci prostego ciągu znaków. W tym właśnie komputery są najlepsze. Algorytm konwersji pomiędzy sekwencją znaków, a wewnętrzną reprezentacją jest dość skomplikowany.

5
Advertisement
5
5
2014-01-11 17:59:58 +0000

W przypadku, gdy chciałbyś otrzymać praktyczny przykład jak wiele programów w typowym systemie Linux obsługuje dużą liczbę operacji przetwarzania i wyjścia:

libgmp - The GNU Multiple Precision Arithmetic Library jest najczęściej używaną w tym celu biblioteką w systemach Linux. Prosty przykład mnożenia 2^80 przez 1000:

#include <gmp.h>

// Each large integer uses the mpz_t type provided by libgmp
mpz_t a_large_number;
mpz_t base;
mpz_t result;

// Initalize each variable
mpz_init(a_large_number);
mpz_init(base);
mpz_init(result);

// Assign the number 2 to the variable |base|
mpz_set_ui(base, 2);

// Raise base^80 (2^80), store the result in |a_large_number|
mpz_pow_ui(a_large_number, base, 80);

// Multiply |a_large_number| by 1000, store the result in |result|
mpz_mul_ui(result, a_large_number, 1000);

// Finally, output the result in decimal and hex notation
gmp_printf("decimal: %Zd, hex: %ZX\n", result, result);

Więc w zasadzie jest to to to samo, co użycie zwykłych + - * / operatorów, tylko z biblioteką, aby rozbić liczby i zapisać je wewnętrznie jako wiele słów maszynowych (tj. 32-bitowe) liczby. Istnieją również funkcje typu scanf() do obsługi konwersji wpisów tekstowych na typy liczb całkowitych.

Struktura mpz_t jest dokładnie taka sama, jak w przykładzie Scotta Chamberlaina, który liczył do 6 przy użyciu dwóch rąk. Jest to w zasadzie tablica typów mp_limb_t wielkości słowa maszynowego, a gdy liczba jest zbyt duża, aby zmieścić się w słowie maszynowym, GMP używa wielu mp_limb_t do przechowywania wysokich/niskich części liczby.

5
5
5
2014-01-09 16:36:20 +0000

Jeśli napiszesz 10000000000 na przykład w kalkulatorze, komputer obliczy go jako Numer typu Real z punktem dziesiętnym. Limit na 32 bity, o którym wspomniałeś, dotyka bardziej wszystkich liczb Integer typu bez kropki dziesiętnej**. Różne typy danych używają różnych metod jak dostać się do bitów/bajtów.

Liczby typuInteger : Ta tabela może pomóc Ci złapać punkt http://msdn.microsoft.com/en-us/library/296az74e.aspx ). To dotyka limitów dla C++. Na przykład Numer typu Int64 ma limity od -9223372036854775808 do 9223372036854775807.

Numer typu Real : Numery typu rzeczywistego zawierają wartość z punktem płynięcia i elementem i można wprowadzać znacznie większe liczby, ale z ograniczoną dokładnością/precyzyjnie. 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 być może możesz wpisać lub mieć w rezultacie numer 9.999 x 10^308, czyli teoretycznie będziesz miał 308(+1) cyfr 9, ale tylko 15 najważniejszych cyfr zostanie użytych do jego reprezentacji, reszta zostanie utracona, z powodu ograniczonej precyzji.

Dodatkowo, istnieją różne języki programowania i mogą mieć różne implementacje limitów liczbowych. Można więc sobie wyobrazić, że specjalistyczne aplikacje mogą obsługiwać znacznie większe (i/lub bardziej dokładne/precyzyjne) liczby niż C++.

3
Advertisement
3
3
2014-01-12 00:41:20 +0000

Ponieważ nie jest wyświetlana liczba (jeśli chodzi o komputer), lecz ciąg znaków , lub ciąg cyfr. Pewnie, niektóre aplikacje (jak np. kalkulator, jak sądzę), które zajmują się liczbami, radzą sobie z taką liczbą, jak sądzę. Nie wiem, jakich sztuczek używają… Jestem pewien, że niektóre z innych, bardziej wyszukanych odpowiedzi to pokrywają.

0
0
0
2016-12-30 11:54:31 +0000

Większość treści tej odpowiedzi oryginalnie pochodziła z tej odpowiedzi (napisanej przed tamtym innym pytaniem oznaczonym jako duplikat). Omawiam więc użycie wartości 8-bitowych (chociaż pytanie to dotyczyło wartości 32-bitowych), ale to dobrze, ponieważ wartości 8-bitowe są prostsze do zrozumienia koncepcyjnego, a te same pojęcia dotyczą większych wartości, takich jak 32-bitowa arytmetyka.

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 8-bitowe, to największa liczba jaką możemy otrzymać (0xFF * 0xFF = 0xFE01) to nadal 16 bitów, dwa razy więcej niż 8 bitów.

Teraz możesz założyć, że procesor x-bitowy może śledzić tylko x bitów. (Na przykład, 8-bitowy procesor może śledzić tylko 8 bitów.) To nie jest dokładne. Procesor 8-bitowy odbiera dane w 8-bitowych fragmentach. (Te “fragmenty” mają zazwyczaj formalne określenie: “słowo”. W przypadku procesora 8-bitowego używane są 8-bitowe słowa. Na procesorze 64-bitowym, 64-bitowe słowa mogą być użyte)

Tak więc, gdy dasz komputerowi 3 bajty: Bajt #1: instrukcja MUL Bajt #2: bajty wysokiego rzędu (np. 0xA5) Bajt #3: bajty niższego rzędu (np. 0xCB) Komputer może wygenerować wynik, który jest większy niż 8 bitów. Procesor może wygenerować wyniki w następujący sposób: 0100 0000 0100 0010 xxxx xxxx xxxx xxxx 1101 0111 a.k.a.: 0x4082xxxxxxD7 Teraz pozwól, że zinterpretuję to dla Ciebie: 0x oznacza tylko, że następujące cyfry są w systemie szesnastkowym.
Za chwilę omówię bardziej szczegółowo “40”. 82 jest częścią rejestru “A”, który jest serią 8 bitów. xx i xx są częścią dwóch innych rejestrów, zwanych rejestrem “B” i rejestrem “C”. Powodem, dla którego nie wypełniłem tych bitów zerami lub jedynkami jest to, że instrukcja “ADD” (wysyłana do procesora) może spowodować, że bity te nie zostaną zmienione przez instrukcję (podczas gdy większość innych bitów, których używam w tym przykładzie, może zostać zmieniona, z wyjątkiem niektórych bitów flag). D7 zmieściłoby się w większej ilości bitów, zwanych rejestrem “D”. Rejestr to tylko kawałek pamięci. Rejestry są wbudowane w procesory, więc procesor może uzyskać dostęp do rejestrów bez potrzeby interakcji z pamięcią na pendrive'ie RAM.

Tak więc wynik matematyczny 0xA5 razy 0xCB to 0x82D7.

Teraz, dlaczego bity zostały podzielone na rejestry A i D zamiast na rejestry A i B, albo na rejestry C i D? Cóż, po raz kolejny, jest to przykładowy scenariusz, którego używam, mający być raczej podobny w koncepcji do prawdziwego języka assemblingu (16-bitowy Intel x86, używany przez procesory Intel 8080 i 8088 oraz wiele nowszych procesorów). Mogą istnieć pewne wspólne reguły, takie jak rejestr “C” używany zazwyczaj jako indeks do operacji liczenia (typowy dla pętli), czy rejestr “B” używany do śledzenia offsetów, które pomagają określić lokalizację pamięci. Tak więc, “A” i “D” mogą być bardziej powszechne dla niektórych typowych funkcji arytmetycznych.

Każda instrukcja CPU powinna mieć jakąś dokumentację, używaną przez osoby programujące w Assembly. Dokumentacja ta powinna określać, jakie rejestry są wykorzystywane przez każdą instrukcję. (Tak więc wybór, które rejestry mają być używane, jest często określany przez projektantów CPU, a nie przez programistów języka Assembly. )

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 swoją nazwę. Na przykład, istnieje bit “overflow”, który CPU może ustawić, jeśli wynik jest większy niż miejsce, które może przechowywać jeden bajt wyników. (Bit “overflow” często może być oznaczony skróconą nazwą “OF”. To jest kapitał o, a nie zero). Oprogramowanie może sprawdzić wartość tej flagi i zauważyć “problem”. Praca z tym bitem jest często obsługiwana w niewidoczny sposób przez języki wyższego poziomu, więc początkujący programiści często nie uczą się interakcji z flagami procesora. Jednakże, programiści Assembly mogą często uzyskać 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 przechowywać tylko 8 bitów niskich w rejestrze A, ignorować rejestr D i określać bit przepełnienia. Następnie, później (po zapisaniu wyników z rejestru A w głównej pamięci RAM), można użyć innej instrukcji ADD, która przechowuje w rejestrze tylko 8 bitów wysokich (ewentualnie w rejestrze A).

(Zwykle jest też flaga “underflow”, w przypadku gdy odejmiesz zbyt dużo, aby zmieścić się w pożądanym wyniku)

Aby pokazać Ci jak bardzo skomplikowane rzeczy się skomplikowały: 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ł procesorem 16-bitowym. Miał 16-bitowe rejestry o nazwach A, B, C i D. AX, BX, CX i DX. Intel 80386 był 32-bitowym procesorem. Miał 32-bitowe rejestry nazwane EAX, EBX, ECX i EDX. Procesory Intel x64 mają 64-bitowe rejestry nazwane RAX, RBX, RCX i RDX. Układy x64 mogą uruchamiać 16-bitowy kod (w niektórych trybach pracy) i mogą interpretować 16-bitowe instrukcje. Bity składające się na rejestr AX to połowa bitów składających się na rejestr EAX, które są połową bitów składających się na rejestr RAX. Zatem za każdym razem, gdy zmieniasz wartość AX, zmieniasz również EAX i RAX, ponieważ bity używane przez AX są częścią bitów używanych przez RAX. (Jeśli zmienisz EAX o wartość, która jest wielokrotnością 65,536, wówczas dolne 16 bitów pozostanie niezmienione, 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.)

Istnieje więcej flag i rejestrów niż tylko te, które wymieniłem. Po prostu wybrałem kilka powszechnie używanych, aby dać prosty koncepcyjny przykład.

Teraz, jeśli jesteś na 8-bitowym CPU, kiedy piszesz do pamięci, możesz znaleźć pewne ograniczenia dotyczące możliwości odwołania się do adresu 8-bitowego, a nie adresu 4-bitowego lub 16-bitowego. Szczegóły będą się różnić w zależności od procesora, ale jeśli masz takie ograniczenia, to procesor może mieć do czynienia z 8-bitowymi słowami, dlatego też najczęściej określa się go jako “8-bitowy procesor”.

Advertisement
Advertisement