it-swarm.com.de

Warum speichern Computer Dezimalzahlen nicht als zweite ganze Zahl?

Computer haben Probleme beim Speichern von Bruchzahlen, bei denen der Nenner etwas anderes als eine Lösung für 2 ^ x ist. Dies liegt daran, dass die erste Ziffer nach der Dezimalstelle 1/2, die zweite 1/4 (oder 1/(2 ^ 1) und 1/(2 ^ 2)) usw. wert ist.

Warum mit allen Arten von Rundungsfehlern umgehen, wenn der Computer den Dezimalteil der Zahl nur als eine weitere ganze Zahl hätte speichern können (was daher genau ist?)

Das einzige, woran ich denken kann, ist das Wiederholen von Dezimalstellen (in Basis 10), aber es hätte eine Edge-Lösung dafür geben können (wie wir es derzeit mit unendlich haben).

25
SomeKittens

Es gibt tatsächlich Zahlenmodi, die das tun.

Bei der BCD-Arithmetik (Binary-Coded Decimal) arbeitet der Computer in Basis 10. Der Grund, warum Sie selten darauf stoßen, ist, dass Speicherplatz verschwendet wird: Jede einzelne Ziffer einer Zahl benötigt mindestens vier Bits, während ein Computer andernfalls bis zu speichern könnte 16 Werte in diesem Raum. (Es kann auch langsamer sein, aber es ist möglich, dass hardwarebeschleunigte BCD-Mathematik gut funktioniert.) Dies ist in der Tat genau das, was die meisten Taschenrechner tun, weshalb es bestimmte Klassen von Rundungsproblemen gibt, die Sie bei einem 5-Dollar-Casio, der Ihr Mittagessen auf einem Desktop-Computer zu sich nimmt, niemals haben werden.

Der andere Weg, den Sie einschlagen können, besteht darin, rationale Zahlen zu verwenden, dh einen Zähler und einen Nenner, die als Ganzzahlen gespeichert sind. Dies ist tatsächlich in fast allen Sprachen verfügbar, genau und ermöglicht es Ihnen, alles in nativen Binärformaten zu speichern. Das Problem ist, dass Benutzer am Ende des Tages wahrscheinlich keine Brüche wie 463/13 oder sogar 35 und 8/13 sehen möchten. Sie wollen 35.615 sehen ... und sobald Sie dort ankommen, stehen Sie vor allen typischen Problemen. Fügen Sie hinzu, dass dieses Format sogar mehr Speicherplatz benötigt und erheblich langsamer als Gleitkomma-Arithmetik sein kann. Sie werden feststellen, dass standardmäßig keine Computer dieses Format verwenden.

Also: Computer können tun, was Sie wollen, aber es ist langsam und es verschwendet Platz, also tun sie es nur, wenn sie es wirklich müssen. Der Rest der Zeit, die Geschwindigkeit und die Platzersparnis von Gleitkomma sind ein besserer Kompromiss.

35

Es gibt zahlreiche Möglichkeiten, Bruchzahlen zu speichern, und jede hat Vor- und Nachteile.

Gleitkomma ist bei weitem das beliebteste Format. Es funktioniert, indem ein Vorzeichen, eine Mantisse und ein vorzeichenbehafteter Exponent der Basis 2 in ganze Zahlen codiert und in eine Reihe von Bits gepackt werden. Zum Beispiel könnten Sie eine 32-Bit-Mantisse von 0.5 (Codiert als 0x88888888) Und einen 32-Bit-Exponenten mit Vorzeichen von +3 (0x00000003) Haben. , was zu 4.0 (0.5 * 2 ^ 3) dekodieren würde. Gleitkommazahlen sind schnell, da sie in Hardware implementiert sind und ihre Genauigkeit mit absoluter Größe skaliert. Das heißt, je kleiner die Zahl ist, desto besser ist Ihre absolute Genauigkeit, sodass der relative Rundungsfehler mit der absoluten Größe konstant bleibt. Floats eignen sich hervorragend für Werte, die aus einem kontinuierlichen Bereich abgetastet wurden, wie z. B. Längen, Schalldruckpegel, Lichtpegel usw., und werden daher häufig in der Audio- und Bildverarbeitung sowie in statistischen Analysen und physikalischen Simulationen verwendet. Ihr größter Nachteil ist, dass sie nicht genau sind, dh zu Rundungsfehlern neigen und nicht alle Dezimalbrüche genau darstellen können. Alle gängigen Programmiersprachen haben eine Art Gleitkomma.

Fixpunkt arbeitet mit ausreichend großen ganzen Zahlen und reserviert implizit einen Teil ihrer Bits für den Bruchteil. Beispielsweise reserviert eine 24,8-Bit-Festkommazahl 24 Bit für den ganzzahligen Teil (einschließlich Vorzeichen) und 8 Bit für den gebrochenen Teil. Wenn Sie diese Zahl um 8 Bit nach rechts verschieben, erhalten Sie den ganzzahligen Teil. Festkommazahlen waren früher beliebt, wenn Hardware-Gleitkommaeinheiten ungewöhnlich oder zumindest viel langsamer als ihre ganzzahligen Gegenstücke waren. Festkommazahlen sind zwar in Bezug auf die Genauigkeit etwas einfacher zu handhaben (schon allein deshalb, weil sie leichter zu überlegen sind), sie sind jedoch in fast jeder anderen Hinsicht den Floats unterlegen - sie haben eine geringere Präzision, einen kleineren Bereich und weil sie extra sind Operationen sind erforderlich, um Berechnungen für die implizite Verschiebung zu korrigieren. Die Festkomma-Mathematik ist heutzutage oft langsamer als die Gleitkomma-Mathematik.

Dezimal Typen funktionieren ähnlich wie Gleitkommazahlen oder Festkommazahlen, sie gehen jedoch von einem Dezimalsystem aus, dh ihr Exponent (implizit oder explizit) codiert die Potenz von 10 und nicht die Potenz von 2. Eine Dezimalzahl könnte beispielsweise eine Mantisse von 23456 Und einen Exponenten von -2 Codieren, und dies würde sich zu 234.56 Erweitern. Dezimalstellen sind langsamer als Gleitkommazahlen, da die Arithmetik nicht fest mit der CPU verbunden ist. Sie eignen sich jedoch ideal für alle Dezimalzahlen, bei denen diese Zahlen genau sein müssen. Die Rundung erfolgt an genau definierten Stellen - Finanzberechnungen, Anzeigetafeln usw. In einige Programmiersprachen sind Dezimaltypen integriert (z. B. C #), für andere sind Bibliotheken erforderlich, um sie zu implementieren. Beachten Sie, dass Dezimalstellen zwar nicht wiederholte Dezimalbrüche genau darstellen können, ihre Genauigkeit jedoch nicht besser ist als die von Gleitkommazahlen. Wenn Sie Dezimalstellen auswählen, erhalten Sie lediglich genaue Darstellungen von Zahlen, die in einem Dezimalsystem genau dargestellt werden können (genau wie Floats binäre Brüche genau darstellen können).

Rational Zahlen speichern einen Zähler und einen Denumerator, wobei normalerweise eine Art Bignum-Integer-Typ verwendet wird (ein numerischer Typ, der so groß werden kann, wie es die Speicherbeschränkungen des Computers zulassen). Dies ist der einzige Datentyp aus der Gruppe, der Zahlen wie 1/3 Oder 3/17 Sowie Operationen darauf genau modellieren kann - Rationals liefern im Gegensatz zu den anderen Datentypen korrekte Ergebnisse für Dinge wie 3 * 1/3. Die Mathematik ist ziemlich einfach, obwohl es ziemlich schwierig ist, einen effizienten Factoring-Algorithmus zu entwickeln. In einige Programmiersprachen sind rationale Typen integriert (z. B. Common LISP). Zu den Nachteilen von Rationals gehört, dass sie langsam sind (viele Operationen erfordern das Reduzieren von Brüchen und das Faktorisieren ihrer Komponenten) und dass viele gängige Operationen schwer oder unmöglich zu implementieren sind. Die meisten Implementierungen verschlechtern die Rationalität in diesem Fall zu einem Float (z. B. wenn Sie aufrufen) sin() auf einer rationalen).

BCD (Binary Coded Decimal) verwendet "Nibbles" (Gruppen von 4 Bits), um einzelne Ziffern zu codieren. Da ein Nibble 16 verschiedene Werte enthalten kann, Dezimalzahlen jedoch nur 10 erfordern, gibt es 6 "unzulässige" Werte pro Nibble. BCD-Zahlen sind wie Dezimalstellen dezimalgenau, dh Berechnungen mit Dezimalzahlen funktionieren genau so, als würden Sie sie mit Stift und Papier ausführen. Arithmetische Regeln für BCD sind etwas umständlich, aber der Vorteil ist, dass das Konvertieren in Zeichenfolgen einfacher ist als bei einigen anderen Formaten, was besonders für ressourcenarme Umgebungen wie eingebettete Systeme interessant ist.

Strings, ja, einfache alte Strings können auch zur Darstellung von Bruchzahlen verwendet werden. Technisch ist dies BCD sehr ähnlich, nur dass es einen expliziten Dezimalpunkt gibt und Sie ein Vollbyte pro Dezimalstelle verwenden. Daher ist das Format verschwenderisch (nur 11 von 256 möglichen Werten werden verwendet), aber es ist einfacher zu analysieren und zu generieren als BCD. Da alle verwendeten Werte "ahnungslos", harmlos und plattformneutral sind, können stringcodierte Nummern außerdem problemlos über Netzwerke übertragen werden. Es ist ungewöhnlich, dass Arithmetik direkt für Zeichenfolgen ausgeführt wird, aber es ist möglich, und wenn Sie dies tun, sind sie genauso dezimalgenau wie die anderen Dezimalformate (Dezimalstellen und BCD).

38
tdammers

Gleitkommazahlen stellen einen großen Wertebereich dar. Dies ist sehr nützlich, wenn Sie nicht im Voraus wissen, wie die Werte lauten könnten, es sich jedoch um einen Kompromiss handelt. Die Darstellung von 1/10 ^ 100 mit einer zweiten Ganzzahl würde nicht funktionieren.

Einige Sprachen (und einige Bibliotheken) weisen andere Merkmale auf. LISP hat traditionell unendlich genaue Ganzzahlen. Cobol hat Berechnungen mit Festkomma-Dezimalzahlen.

Sie müssen Ihre der Problemdomäne entsprechende Nummerndarstellung auswählen.

6
ddyer

Das würde BCD heißen, ich denke, Sie können es immer noch verwenden, wenn Sie wirklich wollen. Es lohnt sich jedoch nicht wirklich als:

  1. Sie werden sehr selten auf einen Rundungsfehler mit 64-Bit-Gleitkomma stoßen
  2. Es macht das Rechnen komplex und ineffizient
  3. Alle 4 Bits werden 6 Werte verschwendet
1
Inverted Llama

Die kurze Antwort lautet: Gleitkomma wurde für wissenschaftliche Berechnungen entwickelt. Es kann eine Zahl mit (bis zu) einer bestimmten Anzahl von signifikanten Stellen speichern, was genau mit der Genauigkeit der meisten wissenschaftlichen Berechnungen übereinstimmt.

Dies wird in der Regel in der Hardware weitgehend unterstützt, da wissenschaftliche Berechnungen in der Regel am meisten von der Hardwareunterstützung profitiert haben. Zum Beispiel werden Finanzberechnungen häufig mit anderen Formaten durchgeführt - aber Finanzsoftware führt normalerweise nur wenig genug echte Berechnungen durch, sodass die Leistung für die meisten Finanzsoftware vollkommen ausreichend bleibt, obwohl die erforderlichen Formate nur in Software unterstützt werden.

1
Jerry Coffin

Es hört sich so an, als würden Sie Festpunkt Zahlen beschreiben.

Beachten Sie, dass das Speichern des Bruchteils einer Zahl an einem separaten Ort genau identisch ist mit dem Erstellen eines einzelnen, doppelt so langen Raums und dem Speichern des gesamten und des Bruchteils in den beiden separaten Hälften. Mit anderen Worten, es ist identisch mit dem Speichern der Zahl als Ganzzahl, nimmt jedoch einfach eine feste Anzahl von Dezimalstellen an.

Normalerweise werden Gleitkommazahlen unter Verwendung einer binären Variation der wissenschaftlichen Notation gespeichert, da es normalerweise auf signifikante Ziffern ankommt. Es gibt jedoch viele andere Methoden. Festkomma-Dezimalzahlen werden häufig zum Speichern von Währungswerten verwendet, wobei die Genauigkeit bis zu einer bestimmten Anzahl von Dezimalstellen kritisch ist, sich die Anzahl der erforderlichen Dezimalstellen jedoch nie ändert.

1
tylerl