Jeśli maszyny 32-bitowe mogą obsługiwać tylko liczby do 2 ^ 32, to dlaczego mogę pisać 1000000000000 (bilionów) bez awarii mojego komputera?


370

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?


35
Pytanie jest błędne. Maszyny 32-bitowe mogą obsługiwać liczby znacznie większe niż 2 ^ 32. Robią to cały czas, z „długim” i tak dalej. Mogą przechowywać maksymalnie 2 ^ 32 w jednym rejestrze, ale oprogramowanie jest napisane, aby ominąć ten problem. Niektóre współczesne języki nawet nie mają problemu z długością podanej liczby.
JFA

23
Zachowaj komentarze na temat, uprzejmy i odpowiedni do technicznych aspektów pytania. Prawie 50 komentarzy do żartów musiało już zostać usuniętych i chcielibyśmy uniknąć konieczności blokowania postu. Dziękuję Ci.
nhinkle

6
To pytanie zostało napisane w sposób nieco niechlujny. Co rozumiesz przez „pisanie” i „wyświetlanie” liczby 1000000000000? Kiedy piszesz pytanie, napisałeś numer 1000000000000, a twoja przeglądarka wyświetla go dobrze, zakładam, ale nie powinno to być dziwne dla każdego, kto kiedykolwiek korzystał z komputera. Pytanie wymaga bezpłatnej interpretacji.
HelloGoodbye

7
Szacuje się, że ludzka świadomość zawiera około 50 bitów (gdzieś czytam). Pytanie nie brzmi więc: „Jak pisać 10^9bez awarii komputera?” ale raczej „Jak mogę pisać 10^(18)bez awarii mojego mózgu?”
Hagen von Eitzen

1
Komputery 32-bitowe mogą przechowywać tylko liczby całkowite PODPISANE do 2 ^ 32 - 1. 2 ^ 32 - 1 nie jest nawet równe 2 147 483 647 ... 300 głosów oddanych i nikt nie zdaje sobie z tego sprawy?
Koray Tugay,

Odpowiedzi:


784

Odpowiadam na twoje pytanie, zadając ci inne:

Jak liczyć na palce do 6?

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.


16
Zabawne, @codename. Jak zatem liczyć na palce do 32 lub więcej (tj. Po wyczerpaniu 2 ^ 5)? ;) Analogia przejścia do drugiej ręki jest dobra ... nawet jeśli binarne opóźnia potrzebę przejścia do drugiej ręki. To, co chciałbym zobaczyć, to zliczanie do 1024 lub więcej przy zręczności pedałowej, aby przejść do palców stóp w celu dalszego liczenia w systemie binarnym - do 1 048 575! :) To potencjalnie 20-bitowa moc płyty głównej. : P
J0e3gan

14
Zachowaj komentarze na ten temat i istotne przy omawianiu technicznych aspektów tej odpowiedzi. Ponad 60 komentarzy do żartów zostało już usuniętych z tej odpowiedzi i chcielibyśmy uniknąć konieczności blokowania postu.
nhinkle

@ kryptonim - łatwe, przypisujesz jeden palec jako wskaźnik stosu. Gdy zabraknie Ci palców, dodajesz kwotę do stosu i zaczynasz odliczanie.
Makach

Gdzie się tego nauczyłeś, @codename? Pierwszy raz usłyszałem to od Frederika Pohla, patrz np. Tutaj hjkeen.net/halqn/f_pohl3.htm
Zane

2
Myślę, że to nie jest odpowiedź na odpowiednie pytanie. Odpowiedź @ Bigbio2002 jest prawidłowa. Tutaj „1000000000000” nie jest liczbą, ale tekstem, podobnie jak „adsfjhekgnoregrebgoregnkevnregj”. To, co mówisz, jest prawdą, ale mocno czuję, że to nie jest poprawna odpowiedź. I żeby zobaczyć tak wiele pozytywnych opinii ...
Master Chief

398

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ść binarna 00110000), 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ń 0s i 1s. 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.


22
W rzeczywistości jest to w większości poprawne, ale nie do końca. 32-punktowa liczba zmiennoprzecinkowa prawdopodobnie nie będzie w stanie dokładnie przedstawić 1000000000000. Będzie reprezentować liczbę bardzo zbliżoną do pożądanej liczby, ale nie do końca.
Tim B

6
@TimB: Czy słyszałeś o formacie dziesiętnym32? Jest to część standardu IEEE 754-2008. Ten format jest w stanie poprawnie przedstawić ten numer :)
VX

15
To prawda, że ​​tak. Jednak nie jest to format, który ludzie mają na myśli, gdy mówią „zmiennoprzecinkowe”, co zwykle odnosi się do 32-bitowej liczby zmiennoprzecinkowej przechowywanej i używanej przez standardowe procesory zmiennoprzecinkowe w obecnych komputerach.
Tim B

2
@ TimB rzeczywiście. Najbliższa liczba do liczby, którą można przedstawić jako zmiennoprzecinkową, to 999999995904
greggo

4
@TimB: Ale 64-bitowa liczba zmiennoprzecinkowa może łatwo reprezentować 1000000000000dokładnie. Jest to 10 ^ 12 lub 2 ^ 12 * 5 ^ 12; 5 ^ 12 wymaga 28 bitów mantysy.
Keith Thompson

191

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.

  • 1 bilion to abstrakcyjne pojęcie liczby
  • 1000000000000 to tekst

Naciskając 1raz, a następnie 012 razy wpisujesz tekst. 1wejścia 1, 0wejścia 0. 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 0i 1na binarne, każde słowo w osobnej linii)

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

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:

  • nasz wymyślony komputer używa liczb dziesiętnych zamiast binarnych
  • jeden bajt może zawierać liczby 0..9
  • jedno słowo składa się z dwóch bajtów

Oto pusta pamięć na 2 słowa:

0 0
0 0

Zapiszmy liczbę 4:

0 4
0 0

Dodajmy teraz 9:

1 3
0 0

Zauważ, że oba operandy zmieściłyby się w jednym bajcie, ale nie wynik. Ale mamy inny gotowy do użycia. Teraz zapiszmy 99:

9 9
0 0

Ponownie użyliśmy drugiego bajtu do przechowywania numeru. Dodajmy 1:

0 0
0 0

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ć:

0 0
9 9

A teraz dodaj 1:

0 1
0 0

Stanie się jaśniejszy, jeśli usuniesz spacje oddzielające bajty i znaki nowej linii:

0099    | +1
0100

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:

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

Konwersja takich liczb na system dziesiętny jest jednak trudna. (ale działa całkiem dobrze w systemie szesnastkowym )


21
Twoja odpowiedź brzmi raczej protekcjonalnie. PO wyraźnie mówią o liczbie, a nie tekst: 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 ...
MirroredFate

12
„1 bilion” to także struna
Elzo Valugi

3
@ElzoValugi It is. Musiałem znaleźć sposób na przedstawienie koncepcji liczby abstrakcyjnej, w przeciwieństwie do ciągu reprezentującego liczbę. Uważam, że „1 bilion” to lepszy i mniej dwuznaczny sposób na zrobienie tego (patrz dowód w odpowiedzi).
gronostaj

25
@MirroredFate Nie zgadzam się z „wyraźnie mówi o liczbie”. PO mówi „wyświetlane w porządku”, który wyraźnie jest mówić o tekście „1000000000000” do mnie ...
Joe

4
@yannbane „A” jest postacią, a nie liczbą. „?” jest postacią, a nie liczbą. „1” jest także znakiem, a nie liczbą. Znaki to tylko symbole. Mogą reprezentować cyfry lub liczby, ale z pewnością nie są liczbami. „1” może oznaczać jeden, dziesięć, sto, tysiące itd., To tylko symbol oznaczający cyfrę, która może być liczbą lub jej częścią. „10” (ciąg znaków) może oznaczać dwa, osiem, dziesięć lub szesnaście itd., Ale kiedy mówisz, że masz dziesięć jabłek, używasz cyfry dziesięć i wszyscy wiedzą, co masz na myśli. Istnieje ogromna różnica między znakami a liczbami.
gronostaj

40

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 sarkazmem bardziej 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 0do 2^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)do 2^(n-1)-1- w ten sposób unikamy nieporozumień związanych z dwoma sposobami pisania +0i pisania -0. Tak więc 32-bitowa liczba całkowita ze znakiem zawierałaby wartość od -2147483648do 2147483647. 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 0i 1, 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ętnego 0.1jako 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, 1234100ale zgadzamy się na konwencję, by 1234.100zamiast 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ąca

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

Jest 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.

javascript:alert(0.1+0.2);

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ść .


8
Możesz to zrobić w tej rzeczywistości. Spróbuj to zrobić we wszechświecie Star Trek. Po prostu cofnij się z powodu wszystkich iskier i dymu.
Michael Petrotta

Nie tak dokładnie działa punkt stały. W rzeczywistości jest to system, w którym liczby są skalowane i tendencyjne w celu uzyskania kropki dziesiętnej. W twoim przykładzie skala wynosi 1/1000, ale są też liczby stałoprzecinkowe (szczególnie w grafice komputerowej), takie jak: 0 = 0,0, 255 = 1,0 - skala to 1/255.
Andon M. Coleman,

31

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.


24

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.


15

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.


2
Dobra odpowiedź oprócz szczegółów - 16 bitów przestrzeni adresowej dało ci 64 KB, a nie 32 MB, a maszyny takie jak 286 miały adresy 24-bitowe (dla 16 MB). Ponadto w przypadku adresów 64-bitowych znacznie wykraczasz poza terabajty - bardziej jak 16 eksabajtów - terabajty mieszczą się w granicach, jakie nakładają płyty główne / procesory obecnej generacji - a nie rozmiar adresów.
Phil

4
32-bit odnosi się do rozmiaru słowa maszynowego, a nie adresów pamięci. Jak wspomniał Phil, 286 było 16-bitowym procesorem, ale wykorzystało 24 bity do adresowania poprzez segmentację pamięci. Procesory x86 są 32-bitowe, ale używają adresowania 36-bitowego. Zobacz PAE .
gronostaj

@gronostaj oraz x86 mają adresowanie 32-bitowe od 386 do Pentium.
Ruslan

Głosuj, ponieważ jest to jedyna PRAWIDŁOWA odpowiedź tutaj - 32-bitowe odnosi się do 32-bitowego adresowania pamięci, a nie 32-bitowej arytmetyki.
user1207217

@ user1207217: ?? Więc zgodnie z twoim rozumowaniem, na przykład Z80 lub 8080 są procesorami 16-bitowymi (z powodu 16-bitowego adresowania pamięci i magistrali pamięci)?
pabouk

13

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ść ascii 97, podczas gdy '1'jest reprezentowana przez 49. 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 komputeramibit-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.


2
Nie przegłosowałem, ale z twoją odpowiedzią jest wiele problemów. 1ma 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.
gronostaj

13

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).


Nieprawda, oryginalny procesor Pentium miał 64-bitową szynę danych dla wysokiej przepustowości pamięci, mimo że był to procesor 32-bitowy. 8088 był 16-bitowym procesorem z 8-bitową magistralą danych.
doug65536

10

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.


10

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.


8

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.)


6

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).


To nie do końca prawda; to, co odnosi się do 64 bitów, jest niespójne, ale systemy o szerokości rejestru 64 bity są często nazywane 64 bitami. Wikipedia twierdzi, że „64-bitowa architektura komputera ma na ogół liczby całkowite i adresy rejestrów o szerokości 64 bitów”. Tak, nowoczesna linia produktów x86 (lub AMD-64) ma ogromne rejestry specjalnego przeznaczenia, ale mają 64-bitowe rejestry główne i mogą uzyskać dostęp do 48-52 bitów pamięci; starsze systemy x86 mają 32-bitowe rejestry główne i mają dostęp do 24-36 bitów pamięci, a 8086 został nazwany 16-bitowym układem, miał 16-bitowe rejestry i miał dostęp do 20 bitów pamięci.
prosfilaes

@prosfilaes To wiele cennych informacji, o których mówiłem (nie pamiętałem szczegółów tak samo jak ty). Edytuj to w odpowiedzi.
mafu

6

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 nieze sobą powiązane .

Wyraźnie:

  • „IPv4 / 6” odnosi się do protokołu internetowego , zestawu zasad określających sposób pakowania i interpretacji informacji w Internecie. Podstawowym (lub przynajmniej najbardziej znanym) rozróżnieniem między IPv4 i IPv6 jest to, że przestrzeń adresowa (tj. Zestaw adresów, których można użyć 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 przydzielonych (tj. Odłożonych w celu) identyfikacji nadawcy pakietu i zamierzonego odbiorcy.
    • Analogia niezwiązana z przetwarzaniem: każdy pakiet jest jak list wysłany pocztą ślimakową, a przestrzeń adresowa jest jak liczba znaków, których „wolno” użyć podczas pisania adresu i adresu zwrotnego na kopercie.
    • Nie widzę tego wspomnianego w żadnej z innych odpowiedzi.
  • „Słowa” pamięci komputera (32-bitowe i 64-bitowe) można ogólnie traktować jako najmniejsze dane, z których korzysta komputer lub „myśli”. Te bity danych łączą się, tworząc inne bity danych , takie jak fragmenty tekstu lub większe liczby całkowite.
  • 32-bitowe wskaźniki mogą lub nie mogą być słowa, ale są one jednak traktowane atomowo (jako indywidualne jednostki, które nie może zostać podzielona na mniejsze części). Wskaźniki to najniższy poziom, w jaki komputer może zapisać lokalizację w pamięci dowolnego dowolnego fragmentu danych. Zauważ, że rozmiar wskaźnika używany przez komputer (lub tak naprawdę przez system operacyjny) ogranicza zasięg pamięci, do którego można uzyskać dostęp za pomocą jednego wskaźnika, ponieważ istnieje tylko tyle możliwych lokalizacji pamięci, na które wskaźnik może „wskazywać” ponieważ istnieją możliwe wartości samego wskaźnika. Jest to analogiczne do sposobu, w jaki IPv4 ogranicza zakres możliwych adresów internetowych, ale nie ma takiego ograniczeniaogranicz ilość danych, które mogą być obecne na przykład na określonej stronie internetowej. Jednak rozmiar wskaźnika nie ogranicza rozmiaru samych danych, na które może wskazywać wskaźnik. (Na przykład schematu pozwalającego na przekraczanie zakresu danych przez rozmiar danych, sprawdź strukturę wskaźnika i-węzłów Linuksa . Zauważ, że jest to nieco inne użycie słowa „wskaźnik” niż jest typowe, ponieważ wskaźnik zwykle odnosi się do wskaźnika w pamięć o dostępie swobodnym, a nie miejsce na dysku twardym).
    • Niekomputerowa analogia: hmmmm .... ta jest trochę trudna. Być może system dziesiętny Deweya do indeksowania materiałów bibliotecznych jest nieco podobny? Lub jakikolwiek system indeksowania, naprawdę.
    • Zobacz odpowiedź SiteNook .
    • Proszę zauważyć, że moje wyjaśnienie powyższych wskazówek pomija 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 wskaźnikami, narysowany przeze mnie tryb mentalny zwykle wystarcza do celów praktycznych.
  • Te numery, że komputer jest „w stanie wyświetlić” nie są (dla celów praktycznych) Limited przez sprzętowej lub systemu operacyjnego komputera; są traktowane jak każdy inny tekst.

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 .


Myślę, że odniesieniem do IPv4 było wskazanie, że liczba adresów IPv4 jest skutecznie ograniczona do długości 32-bitowej liczby całkowitej ze znakiem, podczas gdy IPv6 używa 128 bitów i dlatego może mieć wiele rzędów wielkości więcej adresów.
Clonkex,

@Clonkex Możliwe, że to zdecydowanie nie jest pytanie.
Kyle Strand

5

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, 9ale 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 ++.


Ta „odpowiedź” jest nieprawidłowa: kalkulatory używają reprezentacji liczb BCD, aby uniknąć błędów obcięcia. Dziesiętny IE 0.1 nie może być dokładnie reprezentowany jako liczba binarna o skończonej długości.
trociny

5

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:

#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);

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_tjest dokładnie taka jak w przykładzie Scotta Chamberlaina liczenia do 6 za pomocą dwóch rąk. Jest to w zasadzie tablica mp_limb_ttypów maszynowych słów , a gdy liczba jest zbyt duża, aby zmieścić się w maszynowym słowie, GMP używa wielu mp_limb_tdo przechowywania wysokich / niskich części tej liczby.


5

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.

3+3=6

W takim przypadku liczba nadal mieści się w jednym „gnieździe”

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

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”.

987+321 is more difficult.

Być może nauczyłeś się metody w szkole. Algorytm. Algorytm jest dość prosty. Zacznij od dodania dwóch symboli z lewej strony.

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

Następnie przejdź do następnego miejsca i wykonaj ten sam dodatek.

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ępnego numeru.

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

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

1308

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.


W moim umyśle Wiem 36, ale zazwyczaj tylko 16 z nich korzystać.
Kyle Strand

„Komputer używa bitów do kodowania liczb, ale to nie jest ważne”. Bardzo ważne jest, aby użytkownik zapytał o 32-bitowe słowa i jak są one używane do przechowywania liczb większych niż 2 ^ 32-1.
HörmannHH

Nie jest ważne, jak kodujesz liczby w pamięci swojego mózgu. Masz skończoną liczbę reprezentacji; większość nauczyła się 10 różnych symboli. Wewnątrz twojego mózgu jest to prawdopodobnie reprezentowane w postaci tysięcy neuronów i synaps. W komputerze jest reprezentowany w postaci energii elektrycznej lub jej braku na linii zasilającej. Z perspektywy programowania - lub podczas nauki matematyki, nie jest to wcale ważne, z wyjątkiem rzadkiego przypadku, gdy programujesz bezpośrednio dla określonego zestawu procesorów. Pyta o 32 bity vs 64 bity, a nie o poszczególne bity.
frodeborli

3

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.


0

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”.


Czuję, że fragmenty mojej odpowiedzi powtarzają niektóre inne odpowiedzi na to pytanie. Jednak nie zauważyłem tego, kiedy pierwszy raz napisałem treść, ponieważ napisałem to na inne pytanie. Chociaż doceniam odpowiedź Animism, w tym trochę kodu w języku C, czułem, że moja treść zawierała pewne szczegóły na temat działania asemblera, co jest bliższe faktycznym działaniom / projektowi CPU. Zatem moja odpowiedź nie próbuje być odpowiedzią nadrzędną, która jest „lepsza niż” wszystkie inne, ale jedynie uzupełniająca; dodając kolejną perspektywę z dodatkowym wglądem
TOOGAM
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.