Warum nicht einfach Floats als Ganzzahlen speichern

503
Lance Pollard

Es gibt ein paar Fälle von Schwimmern, an die ich denke

// small 1.1 // medium 1.12 // large 1.123 // extra large 1.12398491859158 // ridiculously large 1.198591851958995815915891581958958198595891958199159859 // large to the point of not really being useful except in rare cases like calculating an infinite series 1.198591851958995815915891581958958198595891958199159859198591851958995815915891581958958198595891958199159859198591851958995815915891581958958198595891958199159859198591851958995815915891581958958198595891958199159859 

Es scheint, dass Sie diese Floats als 2 Ganzzahlen darstellen könnten:

1 and 1 1 and 12 1 and 123 etc. 

Die ersten 3 wären also 2 8-Bit-Zahlen, also 2 Bytes.

Sie können auch die größeren Floats mit Ganzzahlen darstellen, die in kleine Brocken zerlegt werden, die zusammengefügt werden. Also 198591851958995815915891581958958198595891958199159859vielleicht ... Nun, ich weiß nicht, wie das funktionieren würde. Das scheint ein BigNumber-Konzept zu sein, mit dem ich nicht so vertraut bin. Ich fange damit an, nur zu verstehen, warum Floats nicht einfach als ganze Zahlen dargestellt werden können.

Ich frage mich, ob man das erklären könnte. Möglicherweise gibt es einen Performance-Hit, den Sie nehmen werden, vielleicht ist der Performance-Hit nur in bestimmten Fällen (Animationen von Millionen von Objekten x / y-Position, zum Beispiel unter 16 ms gehalten). Ich sehe noch nicht (a) wie man Floats auf ideale Weise als Ganzzahlen implementiert oder (b) wie man dies optimal macht, also bin ich mir nicht sicher, ob es überhaupt eine Untersuchung wert wäre. Ich bin mir nicht sicher, ob es Hardware-Gründe gibt, warum ein Ansatz möglicherweise besser ist als der andere.

Der Grund, warum ich mich dafür interessiere, ist, dass ich daran interessiert wäre, willkürliche Präzisions-Floats für mathematische Zwecke darzustellen, während sie gleichzeitig auch mit "kleinen" Floats wie 1.1und 1.123für Animationen oder andere Zwecke umgehen. Und das System hätte nur einen "Zahlentyp", um beide Fälle auf ähnliche Weise zu behandeln.

-3
Bearbeiten Sie die Frage, um sie auf ein bestimmtes Problem zu beschränken, und zwar so detailliert, dass eine angemessene Antwort gefunden wird. Ramhound vor 6 Jahren 0
Denken Sie daran, dass reelle Zahlen nicht notwendigerweise eine endliche Repräsentation haben (denken Sie an pi oder e), und selbst rationale Zahlen können eine endliche Repräsentation haben oder nicht, wenn Sie sich entscheiden, Bruchteile in einer bestimmten Basis darzustellen (z 1/9). Sie müssen also * mit * Genauigkeitsverlusten umgehen (kein Computer verfügt über unendlichen Speicher). Eine wichtige Frage ist, wie man effizient mit dem * umgehen kann. Ihre Wahl der Vertretung wäre zwar grundsätzlich möglich, würde dies jedoch nicht tun. dirkt vor 6 Jahren 0
Sie können nicht garantieren, dass das Ergebnis einer Division oder Multiplikation beliebiger "einfacher Floats" nicht zu einem komplexen Float führt. Mokubai vor 6 Jahren 0

3 Antworten auf die Frage

2
RalfFriedl

Die Float-Darstellung verfügt über eine breite Palette von Werten, die dargestellt werden können, während sie einen festen und kleinen Raum einnimmt, mit einer Genauigkeit, die für viele Anwendungsfälle ausreichend ist.

Wie Sie bemerkt haben, haben sie auch Nachteile, vor allem wenn die Genauigkeit nicht gut genug ist. Es gibt Bibliotheken für eine beliebige Zahl mit beliebiger Genauigkeit (die ebenfalls nicht durch eine Standard-Ganzzahl mit begrenztem Bereich dargestellt wird) und Dezimalstellen oder Gleitkommazahlen mit beliebiger Genauigkeit. Der Nachteil ist, dass sie viel langsamer sind und mehr Speicher verbrauchen.

2
phuclv

Das Speichern von Schwimmern wie Sie sagten, funktioniert nicht. Wie repräsentierst du 1.01, 1.00001 ...? Für die meisten praktischen Zwecke wäre das Speichern des Signifikanten als Ganzes ein Exponent viel besser, da Sie direkt rechnen können, ohne die Operation in den Ganzzahl- und den Bruchteil zu zerlegen

Zum Beispiel würden 2 Floats x × B n und y × B m in der Basis B als (x × B m - n + y) × B m hinzugefügt und als x × y × B m + n multipliziert . Sie brauchen sich nicht um die Stelle zu kümmern, an der sich der Basispunkt befindet, und Sie müssen keine Ziffern zwischen den beiden getrennten Ganzzahl- und Nachkommastellen verschieben

Beim Speichern von Gleitkomma-Typen mit beliebiger Genauigkeit werden Teile der großen Zahl als Ganzzahlen gespeichert. Die Berechnung in beliebiger Genauigkeit kostet jedoch so viel, dass das in den meisten Situationen niemand will. Anstatt gut in ein einzelnes Maschinenwort zu passen, benötigen Sie jetzt viel mehr Speicher für den variierenden Exponenten und die signifikante Größe, was die Leistung zumindest mehrmals beeinträchtigt

Tatsächlich doublereicht es in den meisten Fällen bereits aus, daher unterstützt kaum eine Hardwarearchitektur 128-Bit-Float

Wie viele Dezimalstellen von Pi brauchen wir wirklich?

2
Ramhound

Es scheint, dass Sie diese Floats als 2 Ganzzahlen darstellen könnten:

Sie können diese Werte als 2 Ganzzahlen darstellen, aber das wäre wirklich ineffizient und Sie würden gegen den IEEE 754-Standard verstoßen, der Fließkommazahlen innerhalb einer bestimmten Architektur definiert.

Ich fange damit an, nur zu verstehen, warum Floats nicht einfach als ganze Zahlen dargestellt werden können.

Sie werden tatsächlich durch ganze Zahlen dargestellt. Der IEEE 754-Standard definiert Folgendes für ein Fließkomma-Format. Wie bei jedem Typ, den Sie definieren können, sind Sie auf das beschränkt, was die Architektur versteht, im Fall von Zahlen, die im Wesentlichen Ganzzahlen wären.

Endliche Zahlen, die durch drei ganze Zahlen beschrieben werden können: s = ein Vorzeichen (null oder eins), c = ein Signifikand (oder Koeffizient) mit nicht mehr als p Ziffern, wenn in Basis b geschrieben (dh eine ganze Zahl im Bereich bis 0) zu bp-1) und q = ein Exponent, so dass emin ≤ q + p - 1 ≤ emax ist. Der numerische Wert einer solchen endlichen Zahl ist (−1) s × c × bq. [A] Außerdem gibt es zwei Nullwerte, die als vorzeichenbehaftete Nullen bezeichnet werden: Das Vorzeichenbit gibt an, ob eine Null +0 (positive Null) oder - ist. 0 (negative Null).

Quelle

Der Grund für mich ist, dass ich daran interessiert bin, willkürliche Präzisionsschwebekörper für mathematische Zwecke darzustellen, während sie gleichzeitig mit den üblichen "kleinen" Schwimmern wie 1.1 und 1.123 für Animationen oder andere Zwecke arbeitet. Und das System hätte nur einen "Zahlentyp", um beide Fälle auf ähnliche Weise zu behandeln.

In den meisten Programmiersprachen können Sie einen neuen Typ definieren. Anschließend können Sie ein neues Fließkommaformat definieren, sofern Sie dem Standard folgen. Dies bedeutet, dass der Typ die drei Ganzzahlen behandeln muss, wie sie vom IEEE-Standard definiert sind.

Nicht sicher, ob Sie sagen, die Befolgung des IEEE-Standards mit 3 Ganzzahlen würde zu einer guten Leistung führen oder nicht, verglichen mit der Verwendung der Gleitkomma-Hardwareregister und dergleichen.

Ich werde noch einmal wiederholen, was Sie beschreiben, würde den IEEE-Standard verletzen. Es wäre auch ineffizient. Um den Grund zu verstehen, machen die meisten Programmiersprachen nicht den Versuch, einen Gleitkomma-Typ mit einstelliger Genauigkeit zu definieren. Sie müssen Computerregister verstehen. Die Größe eines Computerregisters ist spezifisch, das heißt, ein 32-Bit-Register speichert 32 Bit, selbst wenn sie alle Nullen enthalten, sodass ein Gleitkommawert mit einstelliger Genauigkeit immer noch ein 32-Bit-Register verwenden würde.

Mit anderen Worten, alle Ihre Beispiele werden bereits durch das bereits vorhandene Gleitkommaformat mit einfacher Genauigkeit behandelt.

enter image description here

Quelle

Sie können ein Format mit einer einzelnen Vorzeichenstelle, einer einzelnen Exponentenstelle und einer einzelnen Bruchzahl definieren. Dies würde jedoch genauso viel Speicher erfordern wie das im Bild beschriebene Format. Aus diesem Grund wäre es also extrem speicherintensiv.

@LancePollard - Ich habe die Antwort aktualisiert, aber der Grund dafür, dass Ihr Denkprozess fehlerhaft ist, liegt darin, dass Sie versuchen, ein Format zu definieren, um etwas zu behandeln, das bereits von einem vorhandenen Format verarbeitet wird. Wenn Sie mehr wissen möchten, müssen Sie mehr recherchieren und ein grundlegendes Verständnis über Fließkommazahlen und deren binäre Darstellung haben. Ramhound vor 6 Jahren 1
@LancePollard - Deshalb habe ich auf den IEEE-Standard verwiesen. Ramhound vor 6 Jahren 0