it-swarm.com.de

Wenn 32-Bit-Computer nur Zahlen bis zu 2 ^ 32 verarbeiten können, warum kann ich dann 1000000000000 (Billionen) schreiben, ohne dass mein Computer abstürzt?

32-Bit-Computer können nur Ganzzahlen mit bis zu 2 Zeichen speichern31 - 1.
Aus diesem Grund sind uns die IPv4-Adressen ausgegangen und wir sind in die 64-Bit-Ära eingetreten.

Allerdings ist die Nummer 231 - 1 (2.147.483.647) ist nicht so groß wie die Zahl 1 (1.000.000.000.000), die ich anscheinend ohne Absturz meines Computers gut darstellen kann.

Kann jemand erklären, warum das so ist?

367
Ben Johnson mk2

Ich beantworte Ihre Frage mit einer anderen:

Wie rechnen Sie mit Ihren Fingern bis 6?

Sie zählen wahrscheinlich mit einer Hand bis zur größtmöglichen Zahl und wechseln dann zu Ihrer zweiten Hand, wenn Ihnen die Finger ausgehen. Computer tun dasselbe, wenn sie einen Wert darstellen müssen, der größer ist als ein einzelnes Register, verwenden sie mehrere 32-Bit-Blöcke, um mit den Daten zu arbeiten.

785

Sie sind richtig, dass ein 32-Bit-Integer kann nicht ein Wert größer als 2 ^ 32-1 halten. Der Wert dieser 32-Bit-Ganzzahl und die Darstellung auf Ihrem Bildschirm sind jedoch zwei völlig verschiedene Dinge. Die gedruckte Zeichenfolge "1000000000000" wird nicht durch eine 32-Bit-Ganzzahl im Speicher dargestellt.

Buchstäblich die Anzahl anzuzeigen „1000000000000“ benötigt 13 Byte Speicher. Jedes einzelne Byte kann einen Wert von bis zu 255 enthalten. Keines von ihnen kann den gesamten numerischen Wert enthalten, wird jedoch einzeln als ASCII Zeichen interpretiert (das Zeichen '0' wird beispielsweise durch den Dezimalwert 48 dargestellt) , Binärwert 00110000), können sie in einem für Sie, einen Menschen, sinnvollen Format aneinander gereiht werden.


Ein verwandtes Konzept in der Programmierung ist typecasting . Auf diese Weise interpretiert ein Computer einen bestimmten Strom von 0s und 1s. Wie im obigen Beispiel kann es als numerischer Wert, als Zeichen oder sogar als etwas ganz anderes interpretiert werden. Während eine 32-Bit-Ganzzahl möglicherweise nicht in der Lage ist, einen Wert von 1000000000000 zu speichern, kann eine 32-Bit-Gleitkommazahl dies unter Verwendung einer völlig anderen Interpretation tun.

Es gibt 64-Bit-Ganzzahlen (die Werte von bis zu 16 Milliarden Milliarden aufnehmen können), Gleitkommawerte sowie spezialisierte Bibliotheken, die mit beliebig großen Datenmengen arbeiten können zahlen.

398
Bigbio2002

In erster Linie können 32-Bit-Computer Zahlen bis zu 2³²-1 in einem einzelnen Computerwort speichern. Maschinenwort ist die Datenmenge, die die CPU auf natürliche Weise verarbeiten kann (dh Operationen mit Daten dieser Größe werden in Hardware implementiert und sind im Allgemeinen am schnellsten durchzuführen). 32-Bit-CPUs verwenden Wörter, die aus 32 Bits bestehen, und können daher Zahlen von 0 bis 2³²-1 in einem Wort speichern.

Zweitens sind 1 Billion und 1000000000000 zwei verschiedene Dinge.

  • 1 Billion ist ein abstrakter Begriff der Zahl
  • 1000000000000 ist Text

Durch Drücken 1 einmal und dann  12 mal tippen Sie Text. 1 Eingaben 1 Eingaben 0. Sehen? Sie tippen Zeichen. Zeichen sind keine Zahlen. Schreibmaschinen hatten überhaupt keine CPU oder Speicher und sie handhabten solche "Zahlen" ziemlich gut, weil es nur Text ist.

Beweisen Sie, dass 1000000000000 keine Zahl ist, sondern Text: kann 1 Billion (in Dezimalzahl) bedeuten ), 4096 (binär) oder 281474976710656 (hexadezimal). Es hat in verschiedenen Systemen noch mehr Bedeutungen. Die Bedeutung von 1000000000000 ist eine Zahl, und das Speichern ist eine andere Geschichte (wir werden gleich darauf zurückkommen).

Zum Speichern des Textes (in der Programmierung heißt er string ) 1000000000000 benötigen Sie 14 Bytes (eins für jedes Zeichen plus ein abschließendes NULL-Byte) das bedeutet im Grunde "die Zeichenfolge endet hier"). Das sind 4 Maschinenwörter. 3 und die Hälfte wären genug, aber wie gesagt, Operationen an Maschinenwörtern sind am schnellsten. Nehmen wir an, dass ASCII für die Textspeicherung verwendet wird. Im Speicher sieht dies folgendermaßen aus: (Konvertieren von ASCII Codes, die 0 und 1 entsprechen, in binäre Codes, jedes Wort in einem eigenen Linie)

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

Vier Zeichen passen in ein Wort, der Rest wird zum nächsten verschoben. Der Rest wird zum nächsten Wort verschoben, bis alles (einschließlich des ersten NULL-Bytes) passt.

Nun zurück zum Speichern von Nummern. Das funktioniert genauso wie bei überfülltem Text, sie werden jedoch von rechts nach links angepasst. Es mag kompliziert klingen, hier ist ein Beispiel. Der Einfachheit halber nehmen wir an, dass:

  • unser imaginärer Computer verwendet dezimal statt binär
  • ein Byte kann Zahlen enthalten 0..9
  • ein Wort besteht aus zwei Bytes

Hier ist ein leerer 2-Wort-Speicher:

0 0
0 0

Speichern wir die Nummer 4:

0 4
0 0

Fügen wir nun 9 hinzu:

1 3
0 0

Beachten Sie, dass beide Operanden in ein Byte passen würden, aber nicht das Ergebnis. Aber wir haben noch einen gebrauchsfertigen. Speichern wir nun 99:

9 9
0 0

Auch hier haben wir das zweite Byte verwendet, um die Nummer zu speichern. Fügen wir 1 hinzu:

0 0
0 0

Whoops ... Das nennt sich Integer Overflow und ist eine Ursache für viele ernste Probleme, manchmal sehr teure .

Wenn wir jedoch einen Überlauf erwarten, können wir dies tun:

0 0
9 9

Und jetzt addiere 1:

0 1
0 0

Es wird klarer, wenn Sie bytetrennende Leerzeichen und Zeilenumbrüche entfernen:

0099    | +1
0100

Wir haben vorausgesagt, dass ein Überlauf auftreten und wir möglicherweise zusätzlichen Speicher benötigen. Der Umgang mit Zahlen ist nicht so schnell wie bei Zahlen, die in einzelne Wörter passen, und muss in Software implementiert werden. Durch Hinzufügen der Unterstützung für Zwei-32-Bit-Wortnummern zu einer 32-Bit-CPU wird diese effektiv zu einer 64-Bit-CPU (jetzt kann sie von Haus aus mit 64-Bit-Nummern arbeiten, oder?).

Alles, was ich oben beschrieben habe, gilt auch für den Binärspeicher mit 8-Bit-Bytes und 4-Byte-Wörtern.

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

Das Konvertieren solcher Zahlen in ein Dezimalsystem ist jedoch schwierig. (aber es funktioniert ziemlich gut mit hexadezimal )

190
gronostaj

Sie können auch "THIS STATEMENT IS FALSE" schreiben, ohne dass Ihr Computer abstürzt :) @ Scotts Antwort ist für bestimmte Berechnungsrahmen genau richtig, aber Ihre Frage, eine große Zahl zu "schreiben" impliziert, dass es sich nur um einfachen Text handelt, zumindest bis er interpretiert wird.

Bearbeiten: jetzt mit weniger Sarkasmus Nützlichere Informationen zu verschiedenen Möglichkeiten, wie ein Nummer im Speicher abgelegt werden kann. Ich werde diese mit höhere Abstraktion beschreiben, d. H. Mit Begriffen, in die ein moderner Programmierer möglicherweise Code schreibt, bevor er ihn zur Ausführung in Maschinencode übersetzt.

Daten auf einem Computer müssen auf einen bestimmten Typ beschränkt sein, und eine Computerdefinition dieses Typs beschreibt, welche Vorgänge mit diesen Daten durchgeführt werden können und wie (dh Vergleichen von Zahlen, Verketten von Text oder XOR ein Boolescher Wert). Sie können einer Zahl nicht einfach Text hinzufügen, genauso wie Sie eine Zahl nicht mit Text multiplizieren können, sodass einige dieser Werte zwischen Typen konvertiert werden können.

Beginnen wir mit vorzeichenlose ganze Zahlen. In diesen Werttypen werden alle Bits zum Speichern von Informationen zu Ziffern verwendet. yours ist ein Beispiel für eine 32-Bit-Ganzzahl ohne Vorzeichen, in der ein beliebiger Wert von 0 bis 2^32-1 gespeichert werden kann. Und ja, je nach Sprache oder Architektur der verwendeten Plattform können 16-Bit-Ganzzahlen oder 256-Bit-Ganzzahlen verwendet werden.

Was ist, wenn Sie negativ werden wollen? Intuitiv ist vorzeichenbehaftete ganze Zahlen der Name des Spiels. Konvention ist, alle Werte von -2^(n-1) bis 2^(n-1)-1 zuzuweisen - auf diese Weise vermeiden wir die Verwechslung mit zwei Arten, +0 und -0 zu schreiben. Eine 32-Bit-Ganzzahl mit Vorzeichen würde also einen Wert von -2147483648 bis 2147483647 enthalten. Ordentlich, nicht wahr?

Ok, wir haben ganze Zahlen behandelt, bei denen es sich um Zahlen ohne Dezimalstelle handelt. Dies auszudrücken ist schwieriger: Der nicht ganzzahlige Teil kann sinnvollerweise nur irgendwo zwischen 0 und 1 liegen, sodass jedes zusätzliche Bit, das zur Beschreibung verwendet wird, die Genauigkeit erhöht: 1/2, 1/4, 1/8 ... Das Problem ist , Sie können eine einfache Dezimalzahl 0.1 nicht genau als Summe von Brüchen ausdrücken, deren Nenner nur Zweierpotenzen haben kann! Wäre es nicht viel einfacher, die Zahl als Ganzzahl zu speichern, aber stimmen Sie zu, stattdessen den Dezimalpunkt zu setzen? Dies nennt man fester Punkt Zahlen, in denen wir 1234100 speichern, uns jedoch auf eine Konvention einigen, die es stattdessen als 1234.100 liest.

Ein relativ gebräuchlicher Typ für Berechnungen ist floating point. Die Art und Weise, wie es funktioniert, ist wirklich ordentlich. Es wird ein Bit zum Speichern des Vorzeichenwerts verwendet, dann ein Bit zum Speichern von Exponenten und Signifikanten. Es gibt Standards, die solche Zuordnungen definieren, aber für ein 32-Bit-Float ist die maximale Anzahl, die Sie speichern können, überwältigend

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

Dies geht jedoch zu Lasten der Präzision. In Browsern verfügbares JavaScript verwendet 64-Bit-Floats und kann die Dinge immer noch nicht richtig machen. Kopieren Sie dies einfach in die Adressleiste und drücken Sie die Eingabetaste. Spoiler-Warnung: Das Ergebnis ist nicht, das 0.3 sein wird.

javascript:alert(0.1+0.2);

Es gibt weitere alternative Typen wie Microsoft .NET 4.5 BigInteger , die theoretisch keine Ober- oder Untergrenze haben und in "Batches" berechnet werden müssen. Aber vielleicht sind die faszinierenderen Technologien jene, die verstehen Mathe, wie die Wolfram Mathematica-Engine, die genau mit abstrakten Werten wie unendlich arbeiten kann.

40
o.v.

Der Schlüssel ist zu verstehen, wie Computer codieren Zahlen.

Wenn ein Computer darauf besteht, Zahlen mit einer einfachen binären Darstellung der Zahl in einem einzelnen Wort (4 Byte in einem 32-Bit-System) zu speichern, kann ein 32-Bit-Computer nur Zahlen bis zu 2 ^ 32 speichern. Aber es gibt viele andere Möglichkeiten, Zahlen zu kodieren, je nachdem, was Sie damit erreichen möchten.

Ein Beispiel ist, wie Computer Gleitkommazahlen speichern. Computer können eine ganze Reihe verschiedener Methoden verwenden, um sie zu codieren. Der Standard IEEE 754 definiert Regeln für die Codierung von Zahlen größer als 2 ^ 32. Grob gesagt können Computer dies implementieren, indem sie die 32 Bits in verschiedene Teile, die einige Ziffern der Zahl darstellen, und andere Bits, die die Größe der Zahl darstellen (d. H. Den Exponenten, 10 ^ x), teilen. Dies ermöglicht einen viel größeren Bereich von Zahlen in Bezug auf die Größe, beeinträchtigt jedoch die Präzision (was für viele Zwecke in Ordnung ist). Natürlich kann der Computer für diese Codierung auch mehr als ein Wort verwenden, wodurch die Genauigkeit der Größe der verfügbaren codierten Zahlen erhöht wird. Die einfache 32-Dezimal-Version des IEEE-Standards ermöglicht Zahlen mit einer Genauigkeit von etwa 7 Dezimalstellen und Zahlen mit einer Größe von bis zu etwa 10 ^ 96.

Es gibt jedoch noch viele andere Optionen, wenn Sie zusätzliche Präzision benötigen. Offensichtlich können Sie mehr Wörter in Ihrer Kodierung ohne Einschränkung verwenden (allerdings mit einem Leistungsnachteil beim Konvertieren in und aus dem kodierten Format). Wenn Sie eine Möglichkeit untersuchen möchten, wie dies getan werden kann, gibt es ein großartiges Open-Source-Add-In für Excel, das ein Kodierungsschema verwendet, das die Berechnung mit einer Genauigkeit von Hunderten von Stellen ermöglicht. Das Add-In heißt Xnumbers und ist hier verfügbar. Der Code ist in Visual Basic, was nicht der schnellste ist, aber den Vorteil hat, dass er leicht zu verstehen und zu ändern ist. Auf diese Weise erfahren Sie, wie Computer längere Zahlen codieren. Und Sie können mit den Ergebnissen in Excel herumspielen, ohne Programmiertools installieren zu müssen.

31
matt_black

Es ist alles in deiner Frage.

Sie können schreiben eine beliebige Zahl auf Papier schreiben. Versuchen Sie, eine Billion Punkte auf ein weißes Blatt Papier zu schreiben. Es ist langsam und unwirksam. Deshalb haben wir ein 10-stelliges System, um diese großen Zahlen darzustellen. Wir haben sogar Namen für große Zahlen wie "Million", "Billion" und mehr, also sagt man one one one one one one one one one one one... nicht laut.

32-Bit-Prozessoren sind so konzipiert, dass sie mit genau 32 Binärziffern langen Speicherblöcken am schnellsten und effizientesten arbeiten. Aber wir, die Menschen, benutzen gewöhnlich ein 10-stelliges numerisches System, und Computer, die elektronisch sind, benutzen ein 2-stelliges System ( binär ). Die Zahlen 32 und 64 sind zufällig Potenzen von 2. Eine Million und eine Billion sind also Potenzen von 10. Es ist für uns einfacher, mit diesen Zahlen zu arbeiten, als zum Beispiel mit einer Vielzahl von 65536.

Wir zerlegen große Zahlen in Ziffern, wenn wir sie auf Papier schreiben. Computer teilen Zahlen in eine größere Anzahl von Ziffern auf. Wir können jede beliebige Zahl aufschreiben, und die Computer auch, wenn wir sie so gestalten.

24
user1306322

32bit und 64bit beziehen sich auf Speicheradressen. Ihr Computerspeicher ist wie ein Postfach, jedes hat eine andere Adresse. Die CPU (Central Processing Unit) verwendet diese Adressen, um Speicherstellen in Ihrem RAM (Random Access Memory) zu adressieren. Wenn die CPU nur 16-Bit-Adressen verarbeiten konnte, konnten Sie nur 32 MB RAM verwenden (was zu diesem Zeitpunkt riesig schien). Mit 32bit ging es auf 4 + GB (was zu der Zeit riesig schien). Jetzt, da wir 64-Bit-Adressen haben, geht RAM in Terabyte über (was riesig erscheint).
Das Programm ist jedoch in der Lage, mehrere Speicherblöcke für die Speicherung von Zahlen und Text zuzuweisen, die dem Programm überlassen sind und nicht mit der Größe der einzelnen Adressen zusammenhängen. Damit ein Programm der CPU mitteilen kann, werde ich 10 Adressblöcke verwenden und dann eine sehr große Zahl oder eine 10-Buchstaben-Zeichenfolge oder was auch immer speichern.
Randnotiz: Auf Speicheradressen wird durch "Zeiger" verwiesen, sodass der 32- und 64-Bit-Wert die Größe des Zeigers bedeutet, der für den Zugriff auf den Speicher verwendet wird.

15
Engineer

Da die Anzeige der Nummer aus einzelnen Zeichen und nicht aus ganzen Zahlen besteht. Jede Ziffer in der Zahl wird durch ein separates Zeichenliteral dargestellt, dessen ganzzahliger Wert durch die verwendete Codierung definiert wird. Beispiel: 'a' wird durch den ASCII-Wert 97 dargestellt, während '1' durch 49 dargestellt wird. Überprüfen Sie die ASCII-Tabelle hier .
Für die Anzeige ist sowohl 'a' als auch '1' gleich. Sie sind Zeichenliterale, keine ganzen Zahlen. Jedes Zeichenliteral darf auf einer 32-Bit-Plattform einen Maximalwert von 255 haben, wobei der Wert in 8-Bit- oder 1-Byte-Größe gespeichert wird (dies ist plattformabhängig, jedoch ist 8-Bit die häufigste Zeichengröße) angezeigt. Wie viele separate Zeichen sie anzeigen können, hängt von Ihrem RAM ab. Wenn Sie nur 1 Byte RAM haben, können Sie nur ein Zeichen anzeigen. Wenn Sie 1 GB RAM haben, können Sie gut 1024 * 1024 * 1024 Zeichen anzeigen (zu faul, um die Berechnung durchzuführen).

Diese Einschränkung gilt jedoch für die Berechnungen, aber ich denke, Sie interessieren sich für den IPV4-Standard. Obwohl es nicht vollständig mit dem bit-size des Computers zusammenhängt, hat es die Standards irgendwie beeinflusst. Beim Erstellen des IPV4-Standards wurden die IP-Werte in 32-Bit-Ganzzahlen gespeichert. Jetzt hast du einmal die Größe angegeben, und es wurde Standard. Alles, was wir über das Internet wissen, war davon abhängig, und dann konnten wir keine IP-Adressen mehr zuweisen. Wenn also der IP-Standard auf 64-Bit überarbeitet wurde, funktioniert einfach alles nicht mehr, einschließlich Ihres Routers (ich nehme an, dass dies korrekt ist) und anderer Netzwerkgeräte. Es muss also ein neuer Standard erstellt werden, der nur die 32-Bit-Ganzzahl durch eine 128-Bit-Ganzzahl ersetzt. Und der Rest des Standards angepasst. Hardware-Hersteller müssen lediglich erklären, dass sie diesen neuen Standard unterstützen, und er wird viral. Es ist zwar nicht so einfach, aber ich denke, Sie haben den Punkt hier.

Haftungsausschluss: Die meisten der hier genannten Punkte stimmen mit meiner Annahme überein. Vielleicht habe ich hier wichtige Punkte verpasst, um es einfacher zu machen. Ich kann nicht gut mit Zahlen umgehen, also muss ich ein paar Ziffern übersehen haben, aber hier geht es darum, auf die Antwort des OP zu antworten, warum es den PC nicht zum Absturz bringt.

13
noob

In Prozessoren gibt es "Wörter". Es gibt verschiedene Wörter. Wenn Leute "32-Bit-Prozessor" sagen, meinen sie meistens "Speicherbusbreite". Dieses Wort besteht aus verschiedenen "Feldern", die sich auf Untersysteme des Computers beziehen, die dem Senden (24 Bits) und Steuern (andere Bits) entsprechen. Bei genauen Zahlen kann ich mich irren, überzeugen Sie sich anhand von Handbüchern.

Ganz anderer Aspekt ist die Berechnung. SSE und MMX-Befehlssätze können lange Ganzzahlen speichern. Die maximale Länge ohne Produktivitätsverlust hängt von der aktuellen SSE Version ab, es handelt sich jedoch immer um ein Vielfaches von 64 Bit.

Gegenwärtige Opteron-Prozessoren können 256-Bit-breite Zahlen verarbeiten (ich bin mir nicht sicher, aber float ist sicher).

Zusammenfassung : (1) Die Busbreite ist nicht direkt mit der Rechenbreite verbunden, (2) sogar verschiedene Wörter (Speicherwort, Registerwort, Buswort usw.) sind nicht miteinander verbunden, außer sie haben einen gemeinsamen Teiler 8 oder 16 oder 24. Viele Prozessoren verwendeten sogar 6-Bit-Word (aber seine Geschichte).

12
sanaris

Der Unterschied besteht darin, wie wir Daten in Computern speichern.

Sie haben Recht, dass wir für eine theoretische 8-Bit-Maschine nur 2 ^ 8-Werte in einem einzelnen Prozessorregister oder einer einzelnen Speicheradresse speichern können. (Bitte beachten Sie, dass dies von "Maschine" zu "Maschine" variiert, basierend auf dem verwendeten Prozessor, der Speicherarchitektur usw. Aber jetzt bleiben wir bei einem hypothetischen "Stereotyp".)

Für eine theoretische 16-Bit-Maschine wäre der Maximalwert in einem Register/Speicherplatz 2 ^ 16, für eine 32-Bit-Maschine 2 ^ 32 usw.

Im Laufe der Jahre haben Programmierer alle Arten von Schikanen entwickelt, um Zahlen zu speichern und zu verarbeiten, die größer sind als die, die in einem einzelnen Prozessorregister oder einer einzelnen Speicheradresse gespeichert werden können. Es gibt viele Methoden, aber alle umfassen die Verwendung von mehr als einer Register-/Speicheradresse, um Werte zu speichern, die größer als ihre "native" Register-/Speicherstellenbreite sind.

Alle diese Methoden haben den Vorteil, dass die Maschine Werte speichern/verarbeiten kann, die größer als ihre native Kapazität sind. Der Nachteil ist, dass fast alle Ansätze mehrere Maschinenbefehle/reads/etc erfordern. um mit diesen Zahlen umzugehen. Für die gelegentlich große Anzahl ist dies kein Problem. Beim Umgang mit Lots großen Zahlen (insbesondere großen Speicheradressen) verlangsamt sich der damit verbundene Overhead.

Daher der allgemeine Wunsch, Register, Speicherstellen und Speicheradressenhardware "breiter" und breiter zu machen, um große Zahlen "nativ" zu behandeln, so dass solche Zahlen mit der minimalen Anzahl von Operationen behandelt werden können.

Da die Anzahl unendlich groß ist, ist das Verhältnis von Prozessorregister/Speichergröße/Adressierung immer ein Gleichgewicht zwischen der nativen Anzahl und den Kosten, die mit der Implementierung immer größerer Breiten verbunden sind.

10
user48420

Der Zweck eines Computergeräts besteht im Allgemeinen darin, Daten zu akzeptieren, zu verarbeiten, zu speichern und zu senden. Die zugrunde liegende Hardware ist lediglich eine Maschine, mit deren Hilfe diese vier Funktionen ausgeführt werden können. Ohne Software geht das nicht.

Software ist der Code, der dem Gerät mitteilt, wie Daten akzeptiert, verarbeitet, gespeichert und an andere weitergegeben werden.

Die zugrunde liegende Hardware unterliegt immer Einschränkungen. Bei einer 32-Bit-Maschine sind die meisten Register, die Daten verarbeiten, nur 32 Bit breit. Dies bedeutet jedoch nicht, dass das Gerät keine Zahlen über 2 ^ 32 verarbeiten kann. Wenn Sie mit größeren Zahlen arbeiten möchten, benötigt das Gerät möglicherweise mehr als einen Zyklus, um sie zu akzeptieren, zu verarbeiten und zu speichern es, oder es ausstrahlen.

Die Software teilt der Maschine mit, wie mit Zahlen umzugehen ist. Wenn die Software für den Umgang mit großen Zahlen ausgelegt ist, sendet sie eine Reihe von Anweisungen an die CPU, die angeben, wie mit den größeren Zahlen umgegangen werden soll. Beispielsweise kann Ihre Nummer durch zwei 32-Bit-Register dargestellt werden. Wenn Sie Ihrer Zahl 1.234 hinzufügen möchten, weist die Software die CPU an, zuerst 1.234 in das untere Register einzufügen und dann das Überlaufbit zu überprüfen, um festzustellen, ob diese Addition zu einer Zahl führt, die für das untere Register zu groß ist. Wenn dies der Fall ist, wird 1 zum oberen Register hinzugefügt.

Auf die gleiche Weise, wie Grundschüler lernen, mit Carry etwas hinzuzufügen, kann die CPU angewiesen werden, mit Zahlen umzugehen, die größer sind, als sie in einem einzelnen Register enthalten können. Dies gilt für die meisten allgemeinen mathematischen Operationen für Zahlen jeder praktischen Größe.

10
Adam Davis

32-Bit-Computer können nur Zahlen bis zu 2 ^ 32 in einem einzelnen Computer-Word speichern. Dies bedeutet jedoch nicht, dass sie keine größeren Datenmengen verarbeiten können.

Die Bedeutung eines 32-Bit-Computers besteht im Allgemeinen darin, dass der Datenbus und der Adressbus 32 Bit breit sind, was bedeutet, dass der Computer 4 GB Speicheradressraum gleichzeitig verarbeiten und jeweils vier Datenbytes über den Datenbus senden kann .

Dies schränkt den Computer jedoch nicht darin ein, mehr Daten zu verarbeiten, sondern muss die Daten lediglich beim Senden über den Datenbus in Vier-Byte-Blöcke aufteilen.

Der normale Intel 32-Bit-Prozessor kann intern 128-Bit-Nummern verarbeiten, sodass Sie problemlos Nummern wie 1000000000000000000000000000000000000000000 verarbeiten können.

Sie können mit viel größeren Zahlen umgehen als mit einem Computer, aber dann müssen die Berechnungen per Software durchgeführt werden. Die CPU verfügt nicht über Anweisungen für den Umgang mit Zahlen, die größer als 128 Bit sind. (Es kann viel größere Zahlen in Form von Gleitkommazahlen verarbeiten, aber dann haben Sie nur eine Genauigkeit von 15 Stellen.)

8
Guffa

Fügen Sie einfach eine Anmerkung zu den vielen anderen Antworten hinzu, da dies eine ziemlich wichtige Tatsache in dieser Frage ist, die übersehen wurde.

"32 Bit" bezieht sich auf die Speicheradressenbreite. Es hat nichts mit der Registergröße zu tun. Viele 32-Bit-CPUs haben wahrscheinlich 64 oder sogar 128-Bit-Register. Insbesondere in Bezug auf die x86-Produktlinie verfügen die neuesten Consumer-CPUs, die alle 64-Bit-CPUs sind, für spezielle Zwecke über bis zu 256-Bit-Register.

Dieser Unterschied zwischen der Registerbreite und der Adressbreite besteht seit jeher, als wir 4-Bit-Register und 8-Bit-Adressen hatten, oder umgekehrt.

Es ist leicht zu erkennen, dass das Speichern einer großen Zahl unabhängig von der Registergröße kein Problem darstellt, wie in anderen Antworten erläutert.

Der Grund, warum die Register, gleich welcher Größe sie auch sein mögen, zusätzlich auch mit größeren Zahlen rechnen können, ist, dass zu große Berechnungen in mehrere kleinere zerlegt werden können, die in die Register passen (es ist nur eine etwas komplizierter in der Realität).

6
mafu

Für den Fall, dass Sie ein praktisches Beispiel möchten, wie viele Programme auf einem typischen Linux-System eine große Anzahl von Verarbeitungen und Ausgaben ausführen:

libgmp - Die GNU Multiple Precision Arithmetic Library ist die auf Linux-Systemen am häufigsten verwendete Bibliothek für diesen Zweck. Ein einfaches Beispiel für das Multiplizieren von 2 ^ 80 mit 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);

Im Grunde ist es dasselbe wie bei der Verwendung der normalen Operatoren + - * /, nur mit einer Bibliothek, um die Zahlen aufzuteilen und intern als Zahlen mit mehreren Maschinen in Word-Größe (d. H. 32-Bit) zu speichern. Es gibt auch Funktionen vom Typ scanf (), mit denen Sie Texteingaben in Ganzzahltypen konvertieren können.

Die Struktur von mpz_t entspricht genau dem Beispiel von Scott Chamberlain, bei dem mit zwei Händen bis 6 gezählt wird. Grundsätzlich handelt es sich um ein Array von mp_limb_t-Typen in Maschinen-Word-Größe. Wenn eine Zahl zu groß ist, um in ein Maschinen-Word zu passen, verwendet GMP mehrere mp_limb_t-Typen, um die hohen/niedrigen Teile der Zahl zu speichern.

5
Animism

Wenn Sie beispielsweise 1000000000000 in den Taschenrechner schreiben, berechnet der Computer dies als Realer Typ Zahl mit Dezimalpunkt . Das von Ihnen erwähnte Limit für 32 Bit berührt mehr alle Ganzzahltypen Zahlen ohne Dezimalpunkt. Unterschiedliche Datentypen verwenden unterschiedliche Methoden, um in Bits/Bytes zu gelangen.

Zahlen vom Typ Integer : Diese Tabelle kann Ihnen dabei helfen, den Punkt zu erfassen ( http://msdn.Microsoft.com/en-us/library/296az74e.aspx ). Dies berührt Grenzen für C++. Beispiel: Int64-Typennummer hat Grenzwerte von -9223372036854775808 bis 9223372036854775807.

Reelle Typenzahlen : Reelle Typenzahlen enthalten einen Wert mit Gleitkomma und Exponent und Sie können viel größere Zahlen eingeben, jedoch mit eingeschränkter Genauigkeit/Präzision. ( http://msdn.Microsoft.com/en-us/library/6bs3y5ya.aspx ) Zum Beispiel hat LDBL (Large Double) in C++ den maximalen Exponenten 308, daher können Sie möglicherweise eine Zahl eingeben oder als Ergebnis haben 9.999 x 10^308 bedeutet, dass Sie theoretisch 308 (+1) Stellen von 9 haben, aber nur 15 der wichtigsten Stellen verwendet werden, um ihn darzustellen. Der Rest geht verloren, da die Genauigkeit begrenzt ist.

Darüber hinaus gibt es verschiedene Programmiersprachen, und sie können unterschiedliche Implementierungen von Zahlenbeschränkungen aufweisen. Sie können sich also vorstellen, dass spezialisierte Anwendungen viel größere (und/oder genauere/genauere) Zahlen verarbeiten können als C++.

5
Dee

In deinem Kopf kennst du nur 10 verschiedene Ziffern. 0 bis 9. Intern in Ihrem Gehirn ist dies sicherlich anders als in einem Computer codiert.

Ein Computer verwendet Bits zum Codieren von Zahlen, aber das ist nicht wichtig. Genau so haben sich Ingenieure entschieden, Dinge zu kodieren, aber das sollten Sie ignorieren. Sie können es sich wie einen 32-Bit-Computer vorstellen, der eine eindeutige Darstellung von mehr als 4 Milliarden verschiedenen Werten aufweist, während wir Menschen eine eindeutige Darstellung für 10 verschiedene Werte haben.

Wann immer wir eine größere Zahl erfassen müssen, verwenden wir ein System. Die am weitesten links stehende Zahl ist die wichtigste. Es ist zehnmal wichtiger als das nächste Mal.

Ein Computer in der Lage zwischen vier Milliarden verschiedenen Werten zu unterscheiden, muß in ähnlicher Weise den Wert ganz links zu machen, in einer Menge von Werten, wie der nächsten Wert in diesem Satz vier Milliarden Mal so wichtig sein. Eigentlich kümmert sich ein Computer gar nicht darum. Sie weist Zahlen keine "Wichtigkeit" zu. Programmierer müssen dafür speziellen Code erstellen.

Immer wenn ein Wert größer wird als die Anzahl der eindeutigen Symbole, 9 in einem menschlichen Verstand, fügen Sie der Zahl auf der linken Seite eine hinzu.

3+3=6

In diesem Fall passt die Nummer immer noch in einen einzelnen "Steckplatz".

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

Der Mensch hat also immer das Problem, nicht genügend eindeutige Symbole zu haben. Wenn der Computer nicht über ein System verfügt, das sich damit befasst, würde er einfach 0 schreiben und dabei vergessen, dass es eine zusätzliche Zahl gibt. Glücklicherweise haben Computer ein "Überlauf-Flag", das in diesem Fall ausgelöst wird.

987+321 is more difficult.

Möglicherweise haben Sie in der Schule eine Methode gelernt. Ein Algorithmus. Der Algorithmus ist recht einfach. Fügen Sie zunächst die beiden Symbole ganz links hinzu.

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

Dann bewegen Sie sich zum nächsten Steckplatz und führen die gleiche Addition durch.

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

Da wir einen Überlauf hatten, bedeutet dies, dass wir zur nächsten Zahl 1 addieren müssen.

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

Es müssen keine weiteren Zahlen hinzugefügt werden, daher erstellen wir einfach einen Slot und fügen 1 ein, da das Überlauf-Flag angehoben wurde.

1308

Ein Computer macht es genauso, außer dass er 2 ^ 32 oder noch besser 2 ^ 64 verschiedene Symbole hat, anstatt nur 10 wie Menschen.

Auf Hardwareebene bearbeitet der Computer einzelne Bits auf genau dieselbe Weise. Zum Glück ist das für Programmierer weggebannt. Bits besteht nur aus zwei Ziffern, da dies in einer Stromleitung leicht darstellbar ist. Entweder ist das Licht an oder es ist aus.

Schließlich könnte ein Computer eine beliebige Zahl als einfache Folge von Zeichen anzeigen. Das können Computer am besten. Der Algorithmus zur Konvertierung zwischen einer Folge von Zeichen und einer internen Darstellung ist recht komplex.

5
frodeborli

Weil Sie keine Zahl anzeigen (was den Computer betrifft), sondern eine Zeichenfolge oder eine Ziffernfolge. Klar, einige Apps (wie der Taschenrechner, denke ich), die sich mit Zahlen befassen, können mit einer solchen Zahl umgehen, denke ich. Ich weiß nicht, welche Tricks sie verwenden ... Ich bin sicher, dass einige der anderen, ausführlicheren Antworten dies abdecken.

3
Rolf

Der größte Teil des Inhalts dieser Antwort stammte ursprünglich aus dieser Antwort (geschrieben, bevor diese andere Frage als Duplikat markiert wurde). Ich diskutiere also die Verwendung von 8-Bit-Werten (obwohl diese Frage zu 32-Bit-Werten gestellt wurde), aber das ist in Ordnung, da 8-Bit-Werte konzeptionell einfacher zu verstehen sind und die gleichen Konzepte für größere Werte wie 32-Bit-Arithmetik gelten.

Wenn Sie zwei 8-Bit-Zahlen hinzufügen, erhalten Sie die größte Zahl (0xFF + 0xFF = 1FE). Wenn Sie zwei 8-Bit-Zahlen multiplizieren, beträgt die größte Zahl, die Sie erhalten können (0xFF * 0xFF = 0xFE01), immer noch 16 Bit, zweimal 8 Bit.

Nun können Sie davon ausgehen, dass ein x-Bit-Prozessor nur x-Bits verfolgen kann. (Zum Beispiel kann ein 8-Bit-Prozessor nur 8 Bits verfolgen.) Das ist nicht korrekt. Der 8-Bit-Prozessor empfängt Daten in 8-Bit-Blöcken. (Diese "Chunks" haben normalerweise einen formalen Ausdruck: ein "Wort". Auf einem 8-Bit-Prozessor werden 8-Bit-Wörter verwendet. Auf einem 64-Bit-Prozessor können 64-Bit-Wörter verwendet werden.)

Also, wenn Sie dem Computer 3 Bytes geben:
Byte # 1: Der MUL-Befehl
Byte Nr. 2: die höherwertigen Bytes (z. B. 0xA5)
Byte Nr. 3: die Bytes niedrigerer Ordnung (z. B. 0xCB)
Der Computer kann ein Ergebnis erzeugen, das mehr als 8 Bit beträgt. Die CPU kann folgende Ergebnisse erzeugen:
0100 0000 0100 0010 xxxx xxxx xxxx xxxx 1101 0111
a.k.a .:
0x4082xxxxD7
Nun, lassen Sie mich das für Sie interpretieren:
0x bedeutet nur, dass die folgenden Ziffern hexadezimal sind.
Ich werde die "40" gleich genauer besprechen.
82 ist Teil des "A" -Registers, bei dem es sich um eine Reihe von 8 Bits handelt.
xx und xx sind Teil von zwei anderen Registern, die als "B" -Register und "C" -Register bezeichnet werden. Der Grund, warum ich diese Bits nicht mit Nullen oder Einsen gefüllt habe, ist, dass ein "ADD" -Befehl (der an die CPU gesendet wird) dazu führen kann, dass diese Bits durch den Befehl unverändert bleiben (wohingegen die meisten anderen Bits, die ich in diesem Beispiel verwende, dies können geändert werden (mit Ausnahme einiger Flag-Bits).
D7 würde in mehr Bits passen, die als "D" -Register bezeichnet werden.
Ein Register ist nur ein Stück Erinnerung. In den CPUs sind Register eingebaut, so dass die CPU auf Register zugreifen kann, ohne mit dem Speicher auf einem RAM -Stick interagieren zu müssen.

Das mathematische Ergebnis von 0xA5 mal 0xCB ist also 0x82D7.

Warum wurden die Bits in die A- und D-Register anstelle der A- und B-Register oder der C- und D-Register aufgeteilt? Nun, noch einmal, dies ist ein Beispielszenario, das ich verwende und dessen Konzept einer realen Assemblersprache ähnelt (Intel x86 16-Bit, wie es von Intel 8080 und 8088 und vielen neueren CPUs verwendet wird). Möglicherweise gibt es einige allgemeine Regeln, z. B. das "C" -Register, das normalerweise als Index für Zählvorgänge verwendet wird (typisch für Schleifen), und das "B" -Register, das zum Verfolgen von Offsets zum Festlegen von Speicherorten verwendet wird. So können "A" und "D" für einige der üblichen arithmetischen Funktionen üblicher sein.

Jeder CPU-Befehl sollte eine Dokumentation enthalten, die von Personen verwendet wird, die in Assembly programmieren. In dieser Dokumentation sollte angegeben werden, welche Register von den einzelnen Befehlen verwendet werden. (Die Auswahl der zu verwendenden Register wird daher häufig von den Entwicklern der CPU und nicht von den Assembler-Programmierern festgelegt. Es kann jedoch eine gewisse Flexibilität geben.)

Kommen wir nun zu "40" im obigen Beispiel zurück: Dies ist eine Reihe von Bits, die oft als "Flags-Register" bezeichnet werden. Jedes Bit im Flags-Register hat einen Namen. Beispielsweise gibt es ein "Überlauf" -Bit, das die CPU möglicherweise setzt, wenn das Ergebnis größer ist als der Speicherplatz, der ein Byte der Ergebnisse speichern kann. (Das "Überlauf" -Bit wird häufig mit dem abgekürzten Namen "OF" bezeichnet. Dies ist ein Großbuchstabe o, keine Null.) Die Software kann den Wert dieses Flags überprüfen und das "Problem" feststellen. Die Arbeit mit diesem Bit wird von höheren Sprachen häufig unsichtbar ausgeführt, sodass Programmieranfänger häufig nicht lernen, wie sie mit den CPU-Flags interagieren. Assembly-Programmierer greifen jedoch häufig auf einige dieser Flags zu, ähnlich wie bei anderen Variablen.

Zum Beispiel könnten Sie mehrere ADD-Anweisungen haben. Ein ADD-Befehl speichert möglicherweise 16 Bit der Ergebnisse im A-Register und im D-Register, während ein anderer Befehl möglicherweise nur die 8 niedrigen Bits im A-Register speichert, das D-Register ignoriert und das Überlaufbit angibt. Dann, später (nach dem Speichern der Ergebnisse des A-Registers in dem Haupt-RAM), könnten Sie einen anderen ADD-Befehl verwenden, der nur die 8 hohen Bits in einem Register (möglicherweise dem A-Register) speichert. Ob Sie möglicherweise ein Überlaufflag verwenden müssten hängt davon ab, welche Multiplikationsanweisung Sie verwenden.

(Es gibt auch häufig ein "Unterlauf" -Flag, falls Sie zu viel subtrahieren, um das gewünschte Ergebnis zu erzielen.)

Um Ihnen zu zeigen, wie kompliziert die Dinge wurden:
Der Intel 4004 war eine 4-Bit-CPU
Der Intel 8008 war eine 8-Bit-CPU. Es hatte 8-Bit-Register mit den Namen A, B, C und D.
Der Intel 8086 war eine 16-Bit-CPU. Es hatte 16-Bit-Register mit den Namen AX, BX, CX und DX.
Der Intel 80386 war eine 32-Bit-CPU. Es hatte 32-Bit-Register mit den Namen EAX, EBX, ECX und EDX.
Die Intel x64-CPUs haben 64-Bit-Register mit den Namen RAX, RBX, RCX und RDX. Die x64-Chips können (in einigen Betriebsmodi) 16-Bit-Code ausführen und 16-Bit-Anweisungen interpretieren. Dabei sind die Bits des AX-Registers die Hälfte der Bits des EAX-Registers, also die Hälfte der Bits des RAX-Registers. Wenn Sie also den Wert von AX ändern, ändern Sie auch EAX und RAX, da die von AX verwendeten Bits Teil der von RAX verwendeten Bits sind. (Wenn Sie den EAX um ein Vielfaches von 65.536 ändern, bleiben die niedrigen 16 Bits unverändert, sodass sich AX nicht ändert. Wenn Sie den EAX um einen Wert ändern, der kein Vielfaches von 65.536 ist, wirkt sich dies auch auf AX aus .)

Es gibt mehr Flaggen und Register als nur die, die ich erwähnt habe. Ich habe einfach einige häufig verwendete ausgewählt, um ein einfaches konzeptionelles Beispiel zu liefern.

Wenn Sie auf einer 8-Bit-CPU arbeiten und in den Speicher schreiben, können Sie möglicherweise Einschränkungen feststellen, wenn Sie auf eine Adresse mit 8 Bits verweisen möchten, nicht auf eine Adresse mit 4 Bits oder 16 Bits. Die Details variieren je nach CPU, aber wenn Sie solche Einschränkungen haben, kann die CPU mit 8-Bit-Wörtern arbeiten, weshalb die CPU am häufigsten als "8-Bit-CPU" bezeichnet wird.

0
TOOGAM