Der ursprüngliche binäre Suchalgorithmus im JDK verwendete 32-Bit-Ganzzahlen und hatte einen Überlauffehler, wenn (low + high) > INT_MAX
( http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html ) .
Wenn wir denselben binären Suchalgorithmus mit (vorzeichenbehafteten) 64-Bit-Ganzzahlen low + high
umschreiben , können wir dann davon ausgehen, dass INT64_MAX niemals überschritten wird, da es physikalisch unmöglich ist, 10 ^ 18 Byte Speicher zu haben?
Ist es bei Verwendung von (vorzeichenbehafteten) 64-Bit-Ganzzahlen zur Darstellung physikalischer Größen vernünftig anzunehmen, dass kein Unter- und Überlauf auftreten kann?
design
algorithms
Siqi Lin
quelle
quelle
Antworten:
Die kurze Antwort lautet nein. Bei einigen Anwendungen ist Ihre Annahme jedoch möglicherweise richtig.
Angenommen, ein vorzeichenbehaftetes int, 2 ^ 63, mit Kommas zur Verdeutlichung hinzugefügt, = 9.223.372.036.854.775.808. Es ist also ungefähr 9 * 10 ^ 18. 10 ^ 18 ist eine "Exa".
Laut Wikipedia hat das World Wide Web 2013 schätzungsweise 4 Zettabyte erreicht [12], was 4000 Exabyte entspricht. Daher ist das WWW ungefähr 400-mal größer als 2 ^ 63 Bytes.
Daher gibt es mindestens eine physikalische Größe, die viel größer ist als eine 64-Bit-Ganzzahl mit oder ohne Vorzeichen. Angenommen, Ihre Einheiten sind Bytes . Wenn Ihre Einheiten viel größer wären, wie GigaBytes, dann wären Sie in Ordnung, aber Ihre Messgenauigkeit wäre gering.
Ein weiteres Beispiel sind weit entfernte Galaxien. Die Andromeda-Galaxie ist tatsächlich eine der engsten, und sie ist 2,5 * 10 ^ 6 Lichtjahre entfernt. Wenn Ihre Einheiten Meilen wären, wäre dies 14,5 * 10 ^ 18, also mehr als eine 64-Bit-Ganzzahl mit Vorzeichen. Nun hängt es natürlich von den Einheiten ab, die Sie für Ihre Messungen verwenden, aber einige Galaxien sind weit entfernt von Andromeda. ( Der am weitesten bekannte Wert ist 13 * 10 ^ 9 LY entfernt. ) Abhängig von der für Ihre Messung gewünschten Genauigkeit kann eine 64-Bit-Ganzzahl überlaufen.
( Hinzugefügt ) Ja, Meilen sind eine miese Einheit für astronomische Entfernungen. Eine normalere Einheit könnte eine astronomische Einheit sein , ungefähr 150 Millionen Kilometer. Unter Verwendung dieser Maßeinheit ist die am weitesten bekannte Galaxie ungefähr 10 ^ 15 AU (wenn meine Mathematik richtig ist), was in eine 64-Bit-Ganzzahl passen würde. Wenn Sie jedoch auch die Entfernung zum Mond oder zu umlaufenden Satelliten in der Nähe messen möchten, ist diese Einheit zu groß.
Ein weiteres Beispiel aus der Elektronik: der Farad (F), eine Kapazitätseinheit . Große Kondensatoren reichen bis zu 5 kF. Und diese Zahl wird wahrscheinlich mit der Zeit zunehmen, wenn sich Hybridautos, "Smart Grids" usw. verbessern. Once kann eine Kapazität von nur 10 ^ -18 F messen. Der Gesamtbereich der "realen" Kapazität, den wir heute messen können, ist also 5 * 10 ^ 21, größer als eine 64-Bit-Ganzzahl.
quelle
Sie müssen nicht einmal kosmisch werden, wenn es um Kombinatorik geht. Es gibt 2 ^ 95 mögliche Deals in einem Brückenspiel und das ist etwas komplexer.
quelle
Die für Ihre Frage relevanteste physikalische Größe ist der Arbeitsspeicher des Computers .
Windows Server 2012 unterstützt bis zu 4 TB physischen Speicher. Das sind 2 42 Bytes. Wenn sich die RAM-Kapazitäten jedes Jahr weiter verdoppeln, unterstützt "Windows Server 2032" in nur 17 Jahren 2 62 Byte physischen Speicher. Zu diesem Zeitpunkt
low + high
erreichen Sie 2 63 - 2 und küssen die maximale 64-Bit-Ganzzahl mit Vorzeichen.Ich hoffe, dass keine sicherheitskritischen Systeme ausfallen, davon auszugehen, dass 64 Bit immer ausreichen werden.
Für eine etwas allgemeinere Verwendung ist die relevanteste physikalische Größe der Speicheradressraum . (Es ist nützlich, einen viel größeren Adressraum als den physischen Speicher zu haben, z. B. um viele Stapel im Speicher abzulegen, die alle Platz zum Wachsen bieten .) Aktuelle x86-64- Implementierungen unterstützen virtuelle 48-Bit-Adressen, sodass wir nur 14 Jahre Zeit haben, bevor diese CPUs erreicht werden die 2 62- Byte-Adressraumbegrenzung.
Und dann gibt es einen verteilten gemeinsam genutzten Speicher, "in dem die (physisch getrennten) Speicher als ein (logisch gemeinsam genutzter) Adressraum adressiert werden können".
quelle
0xFFFFFFFFxxxxxxxx
(dh der höheren Hälfte ) stoßen , zum Beispiel auf das Betriebssystem oder Gerätetreiber.Nicht genau. Es gibt viele Zahlen, die sowohl größer als auch kleiner sind. Deshalb haben wir Gleitkommazahlen. Gleitkommazahlen tauschen weniger Präzision gegen bessere Reichweite aus.
In dem konkreten Beispiel, das Sie zitiert haben, ist es sehr unwahrscheinlich, dass Sie jemals eine größere Zahl benötigen würden. 64 Bit entsprechen ungefähr 18 Trillionen Elementen. Aber sag niemals nie.
quelle
Ihre Annahme behandelt keine physikalischen Größen, die nur durch Gleitkommazahlen dargestellt werden können. Und selbst wenn Sie sich entschlossen haben, alle Zahlen zu skalieren, indem Sie beispielsweise alle Zahlen mit 10000 multiplizieren (die Werte sind also immer noch ganze Zahlen, können aber in Zehntausendsteln dargestellt werden), schlägt dieses Schema für Zahlen nahe Null, beispielsweise die Elektronenmasse, immer noch fehl (9,1094 * 10 & supmin; ¹ kg).
Das ist eine sehr reale (und extrem kleine) physikalische Größe . Hier sind noch einige , mit denen Sie Probleme haben werden. Und wenn Sie argumentieren, dass dies keine reale physikalische Größe ist (obwohl sie in kg angegeben ist), bedenken Sie Folgendes:
Sie sehen also, wohin ich damit gehe. Das letzte, mit dem du nicht fertig wirst.
Natürlich können Sie ein spezielles Feld in der Zahl haben, um einen ganzzahligen Teil mit einem variablen Multiplikator nach oben oder unten zu skalieren. Jetzt hast du das Fließkomma erfunden.
quelle
Zunächst würde ich die Frage beantworten, welche physikalischen Werte durch eine ganze Zahl dargestellt werden können / sollen.
Eine Ganzzahl ist eine Darstellung einer natürlichen Zahl (und ihrer Unterschiede) in einem Computersystem, daher ist es falsch, sie auf irgendetwas anderes anzuwenden. Das Aufrufen von Entfernungen oder anderen Größen, die zu einer kontinuierlichen Domäne gehören, ist daher kein Argument. Für solche Größen gibt es reelle Zahlendarstellungen. Und Sie können immer eine beliebig große Einheit auswählen und jeden Wert mit einer bestimmten Genauigkeit anpassen.
Was sind also physikalische Werte, die natürliche Zahlen sind und 64-Bit-Ganzzahlen überlaufen können?
Ich kann mir zwei vorstellen. Anzahl physikalischer Objekte (wie Atome) und Energieniveaus, in denen sich ein Quantensystem befinden kann. Dies sind zwei Dinge, die streng ganzzahlig sind. Nun, ich weiß, Sie können ein Atom teilen, aber es erzeugt immer noch eine ganze Zahl und Sie können es nicht auf unbestimmte Zeit teilen. Beide können den 64-Bit-Bereich vorzeichenloser Ganzzahlen leicht übertreffen . Die Anzahl der Atome ist höher und ein Atom kann sich in mehr als einem Energiezustand befinden.
Ob Informationen physisch sind oder nicht, ist sehr umstritten. Ich würde sagen, dass es nicht ist. Daher würde ich nicht sagen, dass die Informationsmenge eine physische Sache ist. Ist also nicht die Größe des Arbeitsspeichers oder so etwas. Wenn Sie dies zulassen würden, dann würde die Anzahl der Atome diese Anzahl leicht überschreiten, da Sie mit der heutigen Technologie mehr als ein Atom benötigen, um ein Bit zu speichern.
quelle
Zusätzlich zur Antwort von Jerry101 möchte ich diesen sehr einfachen und praktischen Test für die Richtigkeit anbieten:
Angenommen, Sie weisen
malloc
in einem 64-Bit-Betriebssystem etwas Speicher über zu . Angenommen, der Speicherzuordner gibt einen gültigen Speicherblock mit der von Ihnen angeforderten Größe zurück, wobei jedoch das 63. Bit gesetzt ist.Mit anderen Worten, nehmen wir an, es gibt einige Programmierumgebungen, in denen
0xFFFFFFFFxxxxxxxx
es sich um legitime Speicherbereiche handelt, die von einem Aufruf an zurückgegeben werden könnenmalloc
.Die Frage ist, wird Ihr Code noch wie vorgesehen funktionieren?
Wenn die analoge Situation für 32-Bit-Betriebssysteme auftritt, funktionierte einige Software nicht ordnungsgemäß, wenn ihnen Speicheradressen "in der oberen Hälfte" zugewiesen wurden. Ursprünglich galt die Verfügbarkeit solcher Speicheradressen nur für den privilegierten Code (Betriebssysteme, Gerätetreiber und Peripheriegeräte). Aufgrund der Knappheit des 32-Bit-Adressraums entschieden sich die Anbieter von Betriebssystemen, einen Teil des reservierten Speicherplatzes zur Verfügung zu stellen Anwendungen, die danach fragen.
Glücklicherweise ist es ziemlich unwahrscheinlich, dass diese Situation für eine Weile bei 64-Bit-Programmen auftritt, zumindest nicht in einem Jahrzehnt.
Wenn diese Situation endlich eintritt, bedeutet dies, dass 128-Bit-adressierbare Prozessoren und Betriebssysteme zu diesem Zeitpunkt zum Mainstream geworden wären und dass sie eine "64-Bit-Emulationsumgebung" bereitstellen könnten, um den Betrieb dieser "Legacy-Anwendungen" zu ermöglichen unter Annahmen ähnlich den heutigen 64-Bit-Betriebssystemen.
Beachten Sie schließlich, dass sich diese Diskussion nur auf Speicheradressen konzentriert. Ein ähnliches Problem mit Zeitstempeln muss mit größerer Vorsicht behandelt werden, da bestimmte Zeitstempelformate den Mikrosekunden viele Bits an Genauigkeit zuweisen und daher in Zukunft weniger Bits für die Darstellung der Zeit zur Verfügung stehen. Diese Probleme sind im Wikipedia-Artikel zum Problem des Jahres 2038 zusammengefasst .
quelle
Dies ist eine Frage, die Sie von Fall zu Fall stellen müssen. Sie sollten nicht generell davon ausgehen, dass die 64-Bit-Arithmetik nicht überläuft, da eine böswillige Datenquelle auch dann zu unzumutbaren Mengen führen kann, die möglicherweise überlaufen auf diese Situation vorbereitet, als unerwartet von ihr getroffen zu werden.
In einigen Fällen ist es sinnvoll, Code zu schreiben, der vom Nichtüberlauf von 64-Bit-Zahlen abhängt. Die Hauptklasse des Beispiels, die ich kenne, sind Zähler, bei denen der Zähler jedes Mal erhöht wird, wenn er verwendet wird. Selbst bei einer Rate von einem Inkrement pro Nanosekunde (nicht praktikabel) würde ein Überlauf mehr als ein Jahrhundert dauern.
Beachten Sie, dass es auf den ersten Blick "im Prinzip immer falsch" scheint, sich auf "Zeit bis zum Ausfall" zu verlassen, um die Richtigkeit eines Systems zu gewährleisten. Dies geschieht jedoch immer mit Authentifizierung / Anmeldung. Wenn genügend Zeit vorhanden ist (um brachiales Forcen zu ermöglichen), ist ein solches System (unabhängig davon, ob es auf Passwörtern, privaten Schlüsseln, Sitzungstoken usw. basiert) defekt.
quelle
Ist es MÖGLICH, dass eine physikalische Größe nicht in 64 Bit passt? Na sicher. Andere haben darauf hingewiesen, die Anzahl der Atome in der Sonne oder die Anzahl der Millimeter bis zur nächsten Galaxie zu zählen. Ob solche Fälle für Ihre Anwendung relevant sind, hängt von Ihrer Anwendung ab. Wenn Sie die Anzahl der Artikel in einem bestimmten Fach in Ihrem Lager zählen, sind wahrscheinlich 16 Bits ausreichend. Wenn Sie Statistiken über die Anzahl der Menschen auf der Welt erstellen, die verschiedene Bedingungen erfüllen, müssen Sie in der Lage sein, Milliarden aufzuzeichnen. Daher benötigen Sie mehr als 32 Bits. Zu diesem Zeitpunkt würden Sie vermutlich auf 64 wechseln (ebenso wenige Computer) haben eingebaute Unterstützung für 37-Bit-Nummern usw.). Wenn es sich um eine Chemieanwendung handelt, die Atome in Mol zählt, sind 64 Bit nicht ausreichend.
Nur weil heutzutage kein Computer über 2 ^ 64 Bytes Arbeitsspeicher verfügt, bedeutet dies technisch nicht zwangsläufig, dass ein Array-Index niemals mehr als 2 ^ 64 sein kann. Es gibt ein Konzept, das als "spärliches Array" bezeichnet wird, bei dem viele Elemente des Arrays nirgendwo physisch gespeichert werden und für solche nicht gespeicherten Werte ein Standardwert wie null oder null angenommen wird. Aber ich nehme an, dass, wenn Sie eine Funktion schreiben, um ein Array oder eine Liste zu durchsuchen, und die Größe des Felds, das Sie verwenden, um den Index im Array zu speichern, mehr als doppelt so groß ist wie die größtmögliche Adresse, und dann nach einem Überlauf suchen, wenn Das Hinzufügen von zwei Indizes wäre nicht unbedingt erforderlich.
quelle
Es ist nicht zumutbar anzunehmen, dass eine 64-Bit-Ganzzahl alle Zahlen enthalten kann. Mehrere Gründe:
Die 64-Bit-Ganzzahlen max und min sind endliche Zahlen. Für jede endliche Zahl existiert eine größere und eine kleinere endliche Zahl.
Berechnungen mit 128-Bit- und 256-Bit-Zahlen werden derzeit an verschiedenen Stellen verwendet. Viele Prozessoren verfügen über spezifische Anweisungen, die 128-Bit-Ganzzahlen verarbeiten.
Vor 20 Jahren galt eine 1-GB-Festplatte als "groß". Heutzutage wird eine 1-TB-Festplatte als klein angesehen. Vor 20 Jahren hatten durchschnittliche Desktops etwa 16 MB RAM. Mein aktueller Desktop hat mehr als 16 GB RAM. Festplattenspeicher und RAM sind in der Vergangenheit exponentiell gewachsen und werden in Zukunft voraussichtlich exponentiell wachsen. Es macht keinen Sinn anzunehmen, dass jemand aufhört zu wachsen, es sei denn, er hat einen guten Grund, warum er aufhören sollte.
quelle