Warum können Dezimalzahlen nicht genau binär dargestellt werden?


284

In SO wurden mehrere Fragen zur Gleitkomma-Darstellung gestellt. Zum Beispiel hat die Dezimalzahl 0.1 keine exakte Binärdarstellung, daher ist es gefährlich, den Operator == zu verwenden, um sie mit einer anderen Gleitkommazahl zu vergleichen. Ich verstehe die Prinzipien hinter der Gleitkomma-Darstellung.

Was ich nicht verstehe, ist, warum aus mathematischer Sicht die Zahlen rechts vom Dezimalpunkt "spezieller" sind als die links?

Zum Beispiel hat die Zahl 61.0 eine genaue binäre Darstellung, da der integrale Teil einer beliebigen Zahl immer genau ist. Die Zahl 6.10 ist jedoch nicht genau. Ich habe nur die Dezimalstelle um eine Stelle verschoben und bin plötzlich von Exactopia nach Inexactville gegangen. Mathematisch sollte es keinen intrinsischen Unterschied zwischen den beiden Zahlen geben - es sind nur Zahlen.

Wenn ich dagegen die Dezimalstelle um eine Stelle in die andere Richtung bewege, um die Zahl 610 zu erhalten, bin ich immer noch in Exactopia. Ich kann weiter in diese Richtung gehen (6100, 610000000, 610000000000000) und sie sind immer noch genau, genau, genau. Sobald die Dezimalstelle einen bestimmten Schwellenwert überschreitet, sind die Zahlen nicht mehr genau.

Was ist los?

Bearbeiten: Um dies zu verdeutlichen, möchte ich mich von Diskussionen über branchenübliche Darstellungen wie IEEE fernhalten und mich an das halten, was ich für den mathematisch "reinen" Weg halte. In Basis 10 sind die Positionswerte:

... 1000  100   10    1   1/10  1/100 ...

In binärer Form wären sie:

... 8    4    2    1    1/2  1/4  1/8 ...

Es gibt auch keine willkürlichen Grenzen für diese Zahlen. Die Positionen erhöhen sich auf unbestimmte Zeit nach links und rechts.


2
Dies kann hilfreich sein, um genau zu verstehen, was in einer Gleitkommazahl vor sich geht: Anatomie einer Gleitkommazahl .
John D. Cook

57
In binärer Form wird die Zahl 3 als 2¹ + 2 ° = 2 + 1 dargestellt. Schön und einfach. Schauen Sie sich jetzt 1/3 an. Wie würden Sie das mit negativen Potenzen von 2 darstellen? Experimentieren Sie ein wenig und Sie werden sehen, dass 1/3 gleich der Summe der unendlichen Folge 2 ^ -2 + 2 ^ -4 + 2 ^ -6 + 2 ^ -8 + ... ist, dh. nicht so einfach, genau in binär darzustellen.
Lars Haugseth

21
Jon Skeet beantwortet die Frage in Ihrem Körper sehr gut. Eine Sache, die fehlt, ist, dass Sie tatsächlich zwei verschiedene Fragen stellen. Die Titelfrage lautet: "Warum können Dezimalzahlen nicht genau binär dargestellt werden?" Die Antwort ist, sie können sein. Zwischen Ihrem Titel und Ihrem Körper verbinden Sie die Idee der "Binärdarstellung" mit der Idee einer "Gleitkommadarstellung". Gleitkomma ist eine Möglichkeit, Dezimalzahlen auf Kosten der Genauigkeit in einer festen Anzahl von Binärziffern auszudrücken. Binär ist nur eine andere Basis für das Zählen und kann bei einer unendlichen Anzahl von Stellen eine beliebige Dezimalzahl ausdrücken.
Chris Blackwell

3
Es gibt mehrere Systeme mit exakter Dezimaldarstellung. Es funktioniert ziemlich genau so, wie Sie es beschreiben. Der SQL-Dezimaltyp ist ein Beispiel. In LISP-Sprachen ist es integriert. Es gibt mehrere kommerzielle und OpenSource-Bibliotheken für die Verwendung exakter Dezimalberechnungen. Es gibt nur keine Hardware-Unterstützung dafür, und nur die meisten Sprachen und Hardware implementiert die IEEE-Standards für die Darstellung einer unendlichen Anzahl von Zahlen in 32 oder 64 Bit.
Nr.

1
Diese Frage scheint nicht zum Thema zu gehören, da es sich um Mathematik handelt (auch wenn es sich um programmierbezogene Mathematik handelt) und besser für Mathematik wäre
Cole Johnson

Antworten:


360

Dezimalzahlen können genau dargestellt werden, wenn Sie genügend Platz haben - nur nicht von schwebenden binären Kommazahlen. Wenn Sie einen Gleitkomma- Dezimalpunkttyp verwenden (z. B. System.Decimalin .NET), können viele Werte, die nicht genau im binären Gleitkomma dargestellt werden können, genau dargestellt werden.

Betrachten wir es anders - in Basis 10, mit der Sie wahrscheinlich vertraut sind, können Sie 1/3 nicht genau ausdrücken. Es ist 0,3333333 ... (wiederkehrend). Der Grund, warum Sie 0.1 nicht als binäre Gleitkommazahl darstellen können, ist genau der gleiche Grund. Sie können 3, 9 und 27 genau darstellen - aber nicht 1/3, 1/9 oder 1/27.

Das Problem ist, dass 3 eine Primzahl ist, die kein Faktor 10 ist. Dies ist kein Problem, wenn Sie eine Zahl mit 3 multiplizieren möchten : Sie können immer mit einer Ganzzahl multiplizieren, ohne auf Probleme zu stoßen. Aber wenn Sie teilen durch eine Zahl , die eine Primzahl ist und kein Faktor Ihrer Basis können Sie in Schwierigkeiten geraten (und wird dies tun , wenn Sie zu teilen versuchen 1 von dieser Zahl).

Obwohl 0,1 normalerweise als einfachstes Beispiel für eine exakte Dezimalzahl verwendet wird, die nicht genau im binären Gleitkomma dargestellt werden kann, ist 0,2 wohl ein einfacheres Beispiel, da es 1/5 ist - und 5 die Primzahl ist, die Probleme zwischen Dezimalzahl und Binärzahl verursacht .


Randnotiz zum Problem der endlichen Repräsentation:

Einige Gleitkomma-Dezimalpunkttypen haben eine feste Größe, System.Decimalandere java.math.BigDecimalsind "beliebig groß" - aber sie stoßen irgendwann an eine Grenze, unabhängig davon, ob es sich um Systemspeicher oder die theoretische maximale Größe eines Arrays handelt. Dies ist jedoch ein völlig anderer Punkt als der Hauptpunkt dieser Antwort. Selbst wenn Sie eine wirklich willkürlich große Anzahl von Bits zum Spielen hätten, könnten Sie die Dezimalzahl 0,1 in einer Gleitkomma-Binärpunktdarstellung nicht genau darstellen. Vergleichen Sie das mit der umgekehrt: Da eine beliebige Anzahl von Dezimalstellen, Sie können genau eine beliebige Anzahl darstellen , die als schwimmende binäre Punkt genau darstellbar ist.


8
Das ist ein verdammt gutes Beispiel, Sir!
Tom Ritter

5
... wünschte, ich könnte dies zweimal positiv bewerten. Ich wurde viel zu oft danach gefragt. Es ist fast so, als könnten die Leute nicht außerhalb der Basis 10 denken. Hehe
Justin Niessner

38
Ja, es gibt 10 Arten von Menschen auf der Welt - diejenigen, die Binärdateien verstehen und diejenigen, die dies nicht tun.
Duffymo

83
@ JonSkeet: Strg + Alt + Entf würde mit nur zwei Fingern unangenehm aussehen.
Lars Haugseth

20
@muusbolla: Nein. Die durch die Dezimaldarstellung 1und die Dezimaldarstellung dargestellten Zahlen 0.9...(unendlich wiederholtes 9s nach dem Dezimalpunkt) sind gleich. Der vielleicht einfachste Weg, dies zu sehen, ist der folgende: Sei x = 0.9.... Beachten Sie das 10x = 9.9..... Deshalb 9x = 10x - x = 9.9... - 0.9... = 9damit 9x = 9und x = 1. Es gibt andere Möglichkeiten, dies zu sehen, aber ich glaube, dass dies die einfachste ist.
Jason

25

Zum Beispiel hat die Zahl 61.0 eine genaue binäre Darstellung, da der integrale Teil einer beliebigen Zahl immer genau ist. Die Zahl 6.10 ist jedoch nicht genau. Ich habe nur die Dezimalstelle um eine Stelle verschoben und bin plötzlich von Exactopia nach Inexactville gegangen. Mathematisch sollte es keinen intrinsischen Unterschied zwischen den beiden Zahlen geben - es sind nur Zahlen .

Lassen Sie uns für einen Moment von den Einzelheiten der Basen 10 und 2 Abstand nehmen. Fragen wir in der Basis b, welche Zahlen terminierende Darstellungen haben und welche nicht? Ein Moment des Gedanke sagt uns , dass eine Zahl mit xeinem Abschluss hat b-Darstellung , wenn und nur wenn es eine ganze Zahl vorhanden , nso dass x b^neine ganze Zahl ist.

So hat zum Beispiel x = 11/500eine abschließende 10-Darstellung, weil wir n = 3und dann x b^n = 22eine ganze Zahl auswählen können . Dies ist x = 1/3jedoch nicht der Fall, da nwir die 3 nicht loswerden können , was auch immer wir auswählen.

Dieses zweite Beispiel veranlasst uns, über Faktoren nachzudenken, und wir können sehen, dass wir für jedes Rationale x = p/q (das in niedrigsten Begriffen angenommen wird) die Frage beantworten können, indem wir die Primfaktoren von bund vergleichen q. Wenn qPrimfaktoren nicht in der Primfaktorisierung von enthalten sind b, werden wir niemals einen geeigneten finden können, um ndiese Faktoren loszuwerden.

So für die Basis 10, eine beliebige p/q , wo qPrimfaktoren andere als 2 oder 5 hat keinen Abschluss Darstellung haben.

p/qWenn wir nun zu den Basen 10 und 2 zurückkehren, sehen wir, dass jedes Rationale mit einer abschließenden 10-Darstellung genau dann die Form hat , wenn qnur 2s und 5s in seiner Primfaktorisierung enthalten sind. und dieselbe Zahl wird genau dann eine abschließende 2-Darstellung haben, wenn qnur 2s in ihrer Primfaktorisierung enthalten ist.

Aber einer dieser Fälle ist eine Teilmenge des anderen! Wann immer

qhat nur 2s in seiner Primfaktorisierung

es ist offensichtlich auch wahr, dass

qhat nur 2s und 5s in seiner Primfaktorisierung

oder anders ausgedrückt, wenn p/qeine terminierende 2-Darstellung p/qeine terminierende 10-Darstellung hat . Das Umgekehrte gilt jedoch nicht - wenn qeine Primfaktorisierung eine 5 enthält, hat sie eine abschließende 10-Darstellung, aber keine abschließende 2-Darstellung. Dies ist das 0.1Beispiel, das in anderen Antworten erwähnt wird.

Da haben wir also die Antwort auf Ihre Frage - da die Primfaktoren von 2 eine Teilmenge der Primfaktoren von 10 sind, sind alle 2-terminierenden Zahlen 10-terminierende Zahlen, aber nicht umgekehrt. Es geht nicht um 61 gegen 6.1 - es geht um 10 gegen 2.

Zum Schluss: Wenn einige Leute die Basis 17 verwenden (sagen wir), aber unsere Computer die Basis 5 verwenden, wäre Ihre Intuition dadurch niemals in die Irre geführt worden - es gäbe keine (nicht null, nicht ganzzahligen) Zahlen, die endeten in beiden Fällen!


Warum zeigt "alert (0.15 * 0.15)" dann "0.0225" an?
Michael Geiser

5
@MichaelGeiser kurze Antwort: Rundung am Anzeigepunkt. Was Sie denken, ist 0.15tatsächlich (wenn als IEEE-Double gespeichert) "0.149999999999999994448884876874". Siehe jsfiddle .
AakashM

Schön klar auf Punkt Code Beispiel! Ich wünschte, ich könnte Ihnen dafür eine Stimme geben! Ich muss mit ein paar Funktionen spielen, um herauszufinden, wo die Abrundung erfolgt. Ich bin immer noch erstaunt, dass wir uns tatsächlich mit diesem Müll befassen müssen. Da die Leute fast zu 100% in der Basis zehn arbeiten und wir so oft Nicht-Ganzzahlen verwenden, dass Sie denken würden, dass die Standardimplementierung der Gleitkomma-Mathematik diesen Unsinn bewältigen würde.
Michael Geiser

1
@MichaelGeiser Die Schaltkreise für die Basis 2 sind kleiner, schneller und energieeffizienter als die für die Basis 10. Heute können wir den Overhead möglicherweise rechtfertigen, aber in den 1970er Jahren, als die Standards festgelegt wurden, war dies eine große Sache. Der Versuch, dies ohne die direkte Unterstützung von Prozessorschaltungen zu tun, ist noch schlimmer. Erwarten Sie Geschwindigkeitsunterschiede um Größenordnungen.
Mark Ransom

Diese Antwort erklärt besser als Jon Skeet selbst!
Goelakash

16

Der (mathematische) Grund ist, dass wenn Sie mit ganzen Zahlen arbeiten, diese zählbar unendlich sind .

Das heißt, obwohl es unendlich viele davon gibt, können wir alle Elemente in der Sequenz "zählen", ohne sie zu überspringen. Das heißt, wenn wir das Element an die 610000000000000dritte Position in der Liste bringen möchten , können wir es über eine Formel herausfinden.

Reelle Zahlen sind jedoch unzählig unendlich . Sie können nicht sagen "Geben Sie mir die reale Nummer an Position 610000000000000" und erhalten Sie eine Antwort zurück. Der Grund dafür ist, dass es auch zwischen 0und 1unendlich viele Werte gibt, wenn Sie Gleitkommawerte berücksichtigen. Gleiches gilt für zwei beliebige Gleitkommazahlen.

Mehr Info:

http://en.wikipedia.org/wiki/Countable_set

http://en.wikipedia.org/wiki/Uncountable_set

Update: Ich entschuldige mich, ich habe die Frage anscheinend falsch interpretiert. In meiner Antwort geht es darum, warum wir nicht jeden realen Wert darstellen können. Ich hatte nicht bemerkt, dass Gleitkomma automatisch als rational klassifiziert wurde.


6
Eigentlich rationale Zahlen sind abzählbar. Aber nicht jede reelle Zahl ist eine rationale Zahl. Ich kann mit Sicherheit eine Folge von exakten Dezimalzahlen erzeugen, die jede exakte Dezimalzahl erreichen, die Sie mir eventuell geben möchten. Wenn Sie sich auch mit irrationalen Zahlen auseinandersetzen müssen, geraten Sie in unzählige unendliche Mengen.
Jon Skeet

Es stimmt, ich sollte "echt" sagen, nicht "Gleitkomma". Wird klarstellen.
TM.

1
Ab diesem Zeitpunkt wird die Logik weniger anwendbar, IMO - denn wir können nicht nur nicht mit allen reellen Zahlen mit binären Gleitkommazahlen umgehen, sondern auch nicht mit allen rationalen Zahlen (wie z. B. 0,1). Mit anderen Worten, ich glaube nicht, dass es wirklich mit Zählbarkeit zu tun hat :)
Jon Skeet

@jonskeet Ich weiß, dass eine Nichtübereinstimmung mit Jon Skeet ein grundlegendes Naturgesetz brechen würde, also werde ich es natürlich nicht tun :) Ich denke jedoch, dass es in Ordnung ist, sich die interne Darstellung der Zahlen als Indizes für a vorzustellen Satz der Werte, die Sie extern darstellen möchten. Mit dieser Denkweise können Sie sehen, dass Sie unabhängig von der Größe Ihrer Indexliste (selbst wenn Sie unendlich viel Präzision gesagt hätten) immer noch nicht alle reellen Zahlen darstellen können.
TM.

3
@TM: Aber das OP versucht nicht, alle reellen Zahlen darzustellen. Er versucht, alle exakten Dezimalzahlen darzustellen , die eine Teilmenge der rationalen Zahlen sind und daher nur zählbar unendlich sind. Wenn er einen unendlichen Satz von Bits als dezimalen Gleitkommatyp verwenden würde, wäre er in Ordnung. Diese Bits werden als binärer Gleitkommatyp verwendet, der Probleme mit Dezimalzahlen verursacht.
Jon Skeet

10

Um zu wiederholen, was ich in meinem Kommentar zu Herrn Skeet gesagt habe: Wir können 1/3, 1/9, 1/27 oder jede rationale Dezimalschreibweise darstellen. Dazu fügen wir ein zusätzliches Symbol hinzu. Zum Beispiel eine Zeile über den Ziffern, die sich in der Dezimalerweiterung der Zahl wiederholen. Was wir brauchen, um Dezimalzahlen als Folge von Binärzahlen darzustellen, sind 1) eine Folge von Binärzahlen, 2) ein Radixpunkt und 3) ein anderes Symbol, um den sich wiederholenden Teil der Folge anzuzeigen.

Hehners Zitatnotation ist ein Weg, dies zu tun. Er verwendet ein Anführungszeichen, um den sich wiederholenden Teil der Sequenz darzustellen. Der Artikel: http://www.cs.toronto.edu/~hehner/ratno.pdf und der Wikipedia-Eintrag: http://en.wikipedia.org/wiki/Quote_notation .

Es gibt nichts, was besagt, dass wir unserem Repräsentationssystem kein Symbol hinzufügen können, sodass wir Dezimalrationen genau in binärer Anführungszeichen darstellen können und umgekehrt.


Dieses Notationssystem funktioniert, wenn wir wissen, wo der Zyklus beginnt und endet. Menschen sind ziemlich gut darin, Zyklen zu erkennen. Aber im Allgemeinen sind Computer nicht. Um ein Wiederholungssymbol effektiv verwenden zu können, müsste der Computer nach einer Berechnung herausfinden können, wo sich die Zyklen befinden. Bei der Zahl 1/3 beginnt der Zyklus beispielsweise sofort. Bei der Zahl 1/97 wird der Zyklus jedoch erst angezeigt, wenn Sie die Antwort auf mindestens 96 Stellen ausgearbeitet haben. (Eigentlich benötigen Sie 96 * 2 + 1 = 193 Stellen, um sicherzugehen.)
Barry Brown

4
Eigentlich ist es für den Computer überhaupt nicht schwer, den Zyklus zu erkennen. Wenn Sie Hehners Artikel lesen, beschreibt er, wie die Zyklen für die verschiedenen arithmetischen Operationen ermittelt werden. Im Divisionsalgorithmus, der wiederholte Subtraktion verwendet, wissen Sie beispielsweise, wo der Zyklus beginnt, wenn Sie einen Unterschied sehen, den Sie zuvor gesehen haben.
Ntownsend

3
Außerdem ging es darum, Zahlen genau darzustellen. Manchmal bedeutet exakte Darstellung viele Bits. Das Schöne an der Anführungszeichenschreibweise ist, dass Hehner zeigt, dass die Darstellungsgröße im Vergleich zur 32-Bit-Standarddarstellung mit fester Länge durchschnittlich 31% einspart.
Ntownsend

6

BCD - Binärcodierte Dezimalzahl - Darstellungen sind genau. Sie sind nicht sehr platzsparend, aber das ist ein Kompromiss, den Sie in diesem Fall für die Genauigkeit eingehen müssen.


1
BCD sind nicht mehr oder weniger genau als jede andere Basis. Beispiel: Wie stellen Sie 1/3 genau in BCD dar? Das kannst du nicht.
Jörg W Mittag

12
BCD ist eine exakte Darstellung eines DEZIMALS, also der "dezimale" Teil seines Namens. Es gibt auch keine exakte Dezimaldarstellung von 1/3.
Alan

4

Es ist der gleiche Grund, warum Sie 1/3 nicht genau in Basis 10 darstellen können, Sie müssen 0,33333 (3) sagen. In der Binärdatei handelt es sich um dieselbe Art von Problem, das jedoch nur bei unterschiedlichen Zahlen auftritt.


4

(Hinweis: Ich werde 'b' anhängen, um hier Binärzahlen anzugeben. Alle anderen Zahlen werden dezimal angegeben.)

Eine Möglichkeit, über Dinge nachzudenken, ist die wissenschaftliche Notation. Wir sind es gewohnt, Zahlen in wissenschaftlicher Notation wie 6.022141 * 10 ^ 23 zu sehen. Gleitkommazahlen werden intern in einem ähnlichen Format gespeichert - Mantisse und Exponent, jedoch mit Zweierpotenzen anstelle von zehn.

Ihre 61.0 könnte mit der Mantisse und den Exponenten als 1.90625 * 2 ^ 5 oder 1.11101b * 2 ^ 101b umgeschrieben werden. Um dies mit zehn zu multiplizieren und (den Dezimalpunkt zu verschieben), können wir Folgendes tun:

(1,90625 * 2 ^ 5) * (1,25 * 2 ^ 3) = (2,3828125 * 2 ^ 8) = (1,19140625 * 2 ^ 9)

oder in mit der Mantisse und Exponenten in binär:

(1.11101b * 2 ^ 101b) * (1.01b * 2 ^ 11b) = (10.0110001b * 2 ^ 1000b) = (1.00110001b * 2 ^ 1001b)

Beachten Sie, was wir dort getan haben, um die Zahlen zu multiplizieren. Wir haben die Mantissen multipliziert und die Exponenten hinzugefügt. Da die Mantisse größer als zwei endete, normalisierten wir das Ergebnis durch Anstoßen des Exponenten. Es ist genau so, als würden wir den Exponenten anpassen, nachdem wir eine Operation mit Zahlen in dezimaler wissenschaftlicher Notation durchgeführt haben. In jedem Fall hatten die Werte, mit denen wir gearbeitet haben, eine endliche Darstellung in Binärform, und so erzeugten die Werte, die durch die grundlegenden Multiplikations- und Additionsoperationen ausgegeben wurden, auch Werte mit einer endlichen Darstellung.

Überlegen Sie nun, wie wir 61 durch 10 teilen würden. Wir beginnen mit der Teilung der Mantissen 1.90625 und 1.25. In Dezimalzahlen ergibt dies 1,525, eine schöne kurze Zahl. Aber was ist das, wenn wir es in eine Binärdatei konvertieren? Wir machen das auf die übliche Weise - subtrahieren die größte Zweierpotenz, wann immer dies möglich ist, genau wie das Konvertieren von ganzzahligen Dezimalstellen in Binärzahlen, aber wir verwenden negative Zweierpotenzen:

1,525 - 1 * 2 ^ 0 -> 1
0,525 - 1 * 2 ^ -1 -> 1
0,025 - 0 * 2 ^ -2 -> 0
0,025 - 0 * 2 ^ -3 -> 0
0,025 - 0 * 2 ^ -4 -> 0
0,025 - 0 * 2 ^ -5 -> 0
0,025 - 1 * 2 ^ -6 -> 1
0,009375 - 1 * 2 ^ -7 -> 1
0,0015625 - 0 * 2 ^ -8 -> 0
0,0015625 - 0 * 2 ^ -9 -> 0
0,0015625 - 1 * 2 ^ -10 -> 1
0,0005859375 - 1 * 2 ^ -11 -> 1
0,00009765625 ...

Oh oh. Jetzt sind wir in Schwierigkeiten. Es stellt sich heraus, dass 1,90625 / 1,25 = 1,525 ein sich wiederholender Bruch ist, wenn er in Binärform ausgedrückt wird: 1,11101b / 1,01b = 1,10000110011 ... b Unsere Maschinen haben nur so viele Bits, um diese Mantisse zu halten, und runden den Bruch nur ab und nehme Nullen über einen bestimmten Punkt hinaus an. Der Fehler, den Sie sehen, wenn Sie 61 durch 10 teilen, ist der Unterschied zwischen:

1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
und sagen wir:
1.100001100110011001100110b * 2 ^ 10b

Es ist diese Rundung der Mantisse, die zu einem Genauigkeitsverlust führt, den wir mit Gleitkommawerten assoziieren. Selbst wenn die Mantisse genau ausgedrückt werden kann (z. B. wenn nur zwei Zahlen addiert werden), können wir dennoch einen numerischen Verlust erhalten, wenn die Mantisse nach dem Normalisieren des Exponenten zu viele Ziffern benötigt, um zu passen.

Wir machen so etwas tatsächlich die ganze Zeit, wenn wir Dezimalzahlen auf eine überschaubare Größe runden und nur die ersten paar Ziffern davon angeben. Da wir das Ergebnis dezimal ausdrücken, fühlt es sich natürlich an. Wenn wir jedoch eine Dezimalstelle runden und sie dann in eine andere Basis konvertieren, sieht sie genauso hässlich aus wie die Dezimalstellen, die wir aufgrund der Gleitkomma-Rundung erhalten.


4

Das ist eine gute Frage.

Alle Ihre Fragen basieren auf "Wie repräsentieren wir eine Zahl?"

ALLE Zahlen können mit Dezimaldarstellung oder mit binärer Darstellung (Zweierkomplement) dargestellt werden. Alle von ihnen !!

ABER einige (die meisten von ihnen) erfordern eine unendliche Anzahl von Elementen ("0" oder "1" für die Binärposition oder "0", "1" bis "9" für die Dezimaldarstellung).

Wie 1/3 in Dezimaldarstellung (1/3 = 0,3333333 ... <- mit einer unendlichen Zahl von "3")

Wie 0,1 in binär (0,1 = 0,00011001100110011 .... <- mit einer unendlichen Zahl von "0011")

Alles ist in diesem Konzept. Da Ihr Computer nur endliche Ziffern (dezimal oder binär) berücksichtigen kann , können nur einige Zahlen in Ihrem Computer genau dargestellt werden ...

Und wie gesagt, Jon, 3 ist eine Primzahl, die kein Faktor 10 ist, so dass 1/3 nicht mit einer endlichen Anzahl von Elementen in Basis 10 dargestellt werden kann.

Selbst mit Arithmetik mit beliebiger Genauigkeit kann das Nummerierungspositionssystem in Basis 2 6.1 nicht vollständig beschreiben, obwohl es 61 darstellen kann.

Für 6.1 müssen wir eine andere Darstellung verwenden (wie die Dezimaldarstellung oder IEEE 854, die Basis 2 oder Basis 10 für die Darstellung von Gleitkommawerten zulässt).


Sie könnten 1/3 als Bruch selbst darstellen. Sie brauchen nicht unendlich viele Bits, um es darzustellen. Sie stellen es einfach als Bruch 1/3 dar, anstatt das Ergebnis von 1 zu nehmen und durch 3 zu teilen. Mehrere Systeme funktionieren auf diese Weise. Sie benötigen dann eine Möglichkeit, die Standard / * + - und ähnliche Operatoren zu verwenden, um an der Darstellung von Brüchen zu arbeiten, aber das ist ziemlich einfach - Sie können diese Operationen mit Stift und Papier ausführen, und es ist keine große Sache, einem Computer beizubringen, dies zu tun .
Nr.

Ich sprach von "binärer (2er-Komplement-) Darstellung". Weil die Verwendung einer anderen Darstellung Ihnen natürlich helfen kann, eine bestimmte Anzahl mit einer endlichen Anzahl von Elementen darzustellen (und für einige andere benötigen Sie eine unendliche Anzahl von Elementen)
ThibThib

3

Wenn Sie mit Gleitkommazahlen eine ausreichend große Zahl erstellen (wie dies bei Exponenten der Fall ist), werden Sie auch vor dem Dezimalpunkt ungenau. Ich glaube also nicht, dass Ihre Frage völlig gültig ist, weil die Prämisse falsch ist. Es ist nicht so, dass eine Verschiebung um 10 immer zu mehr Präzision führt, da die Gleitkommazahl irgendwann Exponenten verwenden muss, um die Größe der Zahl darzustellen, und auf diese Weise auch an Präzision verliert.


3

Ich bin überrascht, dass dies noch niemand gesagt hat: Verwenden Sie fortgesetzte Brüche . Jede rationale Zahl kann auf diese Weise endlich binär dargestellt werden.

Einige Beispiele:

1/3 (0,3333 ...)

0; 3

5/9 (0,5555 ...)

0; 1, 1, 4

10/43 (0,232558139534883720930 ...)

0; 4, 3, 3

9093/18478 (0.49209871198181621387596060179673 ...)

0; 2, 31, 7, 8, 5

Von hier aus gibt es eine Vielzahl bekannter Möglichkeiten, eine Folge von ganzen Zahlen im Speicher zu speichern.

Neben der präzisen Speicherung Ihrer Zahl bieten fortgesetzte Brüche auch einige andere Vorteile, z. B. die beste rationale Approximation. Wenn Sie sich entscheiden, die Zahlenfolge in einem fortgesetzten Bruch vorzeitig zu beenden, erhalten Sie mit den verbleibenden Ziffern (wenn sie zu einem Bruch rekombiniert werden) den bestmöglichen Bruch. So werden Annäherungen an pi gefunden:

Pis fortgesetzte Fraktion:

3; 7, 15, 1, 292 ...

Wenn Sie die Sequenz bei 1 beenden, erhalten Sie den Bruch:

355/113

Das ist eine ausgezeichnete rationale Annäherung.


Aber wie würden Sie das binär darstellen? Zum Beispiel erfordert 15 die Darstellung von 4 Bits, 292 die Darstellung von 9. Woher weiß die Hardware (oder sogar die Software), wo die Bitgrenzen zwischen den einzelnen liegen? Es ist der Kompromiss zwischen Effizienz und Genauigkeit.
glühende

2

In der Gleichung

2^x = y ;  
x = log(y) / log(2)

Daher habe ich mich nur gefragt, ob wir ein logarithmisches Basissystem für binäre wie haben könnten,

 2^1, 2^0, 2^(log(1/2) / log(2)), 2^(log(1/4) / log(2)), 2^(log(1/8) / log(2)),2^(log(1/16) / log(2)) ........

Das könnte das Problem möglicherweise lösen. Wenn Sie also etwas wie 32.41 in Binärform schreiben möchten, wäre dies der Fall

2^5 + 2^(log(0.4) / log(2)) + 2^(log(0.01) / log(2))

Oder

2^5 + 2^(log(0.41) / log(2))

1

Das Problem ist, dass Sie nicht wirklich wissen, ob die Zahl tatsächlich genau 61,0 ist. Bedenken Sie:


float a = 60;
float b = 0.1;
float c = a + b * 10;

Was ist der Wert von c? Es ist nicht genau 61, weil b nicht wirklich .1 ist, weil .1 keine exakte binäre Darstellung hat.


1

Es gibt einen Schwellenwert, da die Bedeutung der Ziffer von einer Ganzzahl zu einer Nicht-Ganzzahl gewechselt ist. Um 61 darzustellen, haben Sie 6 * 10 ^ 1 + 1 * 10 ^ 0; 10 ^ 1 und 10 ^ 0 sind beide ganze Zahlen. 6.1 ist 6 * 10 ^ 0 + 1 * 10 ^ -1, aber 10 ^ -1 ist 1/10, was definitiv keine ganze Zahl ist. So landen Sie in Inexactville.


1

Eine Parallele kann aus Brüchen und ganzen Zahlen bestehen. Einige Brüche, z. B. 1/7, können ohne viele, viele Dezimalstellen nicht in Dezimalform dargestellt werden. Da Gleitkomma binär ist, ändern sich die Sonderfälle, es treten jedoch die gleichen Genauigkeitsprobleme auf.


0

Es gibt unendlich viele rationale Zahlen und eine endliche Anzahl von Bits, mit denen sie dargestellt werden können. Siehe http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems .


Aber selbst mit einer unendlichen Anzahl von Bits könnten Sie , wenn Sie einen Gleitkomma- Binärpunkt verwenden, 0,1 nicht genau darstellen, genauso wie Sie selbst mit einer unendlichen Anzahl von Bits nicht 1/3 genau dezimal darstellen können.
Jon Skeet

3
@ Jon Das ist unwahr: mit einer unendlichen Anzahl von Dezimalstellen, ich kann zum Beispiel Express ‚ein Drittel‘ genau . Das reale Problem ist, dass es physikalisch nicht möglich ist , "eine unendliche Anzahl" von Dezimalstellen oder Bits zu haben.
ChrisW

0

Die Zahl 61.0 hat zwar eine exakte Gleitkommaoperation - dies gilt jedoch nicht für alle Ganzzahlen. Wenn Sie eine Schleife geschrieben haben, die sowohl einer Gleitkommazahl mit doppelter Genauigkeit als auch einer 64-Bit-Ganzzahl eine hinzufügt, erreichen Sie schließlich einen Punkt, an dem die 64-Bit-Ganzzahl eine Zahl perfekt darstellt, der Gleitkomma jedoch nicht. weil es nicht genug signifikante Bits gibt.

Es ist nur viel einfacher, den Approximationspunkt auf der rechten Seite des Dezimalpunkts zu erreichen. Wenn Sie anfangen würden, alle Zahlen in binären Gleitkommazahlen zu schreiben, wäre dies sinnvoller.

Eine andere Art, darüber nachzudenken, ist, dass Sie eine Multiplikation mit Zehnerpotenzen (10 ^ 1, 10 ^ -1) durchführen, wenn Sie feststellen, dass 61.0 in Basis 10 perfekt darstellbar ist und das Verschieben des Dezimalpunkts dies nicht ändert ). Beim Gleitkomma wirkt sich das Multiplizieren mit Zweierpotenzen nicht auf die Genauigkeit der Zahl aus. Nehmen Sie 61.0 und teilen Sie es wiederholt durch drei, um zu veranschaulichen, wie eine perfekt genaue Zahl ihre genaue Darstellung verlieren kann.


0

Sie kennen ganzzahlige Zahlen, oder? Jedes Bit repräsentiert 2 ^ n


2 ^ 4 = 16
2 ^ 3 = 8
2 ^ 2 = 4
2 ^ 1 = 2
2 ^ 0 = 1

Nun, es ist dasselbe für Gleitkomma (mit einigen Unterscheidungen), aber die Bits repräsentieren 2 ^ -n 2 ^ -1 = 1/2 = 0,5
2 ^ -2 = 1 / (2 * 2) = 0,25
2 ^ -3 = 0,125
2 ^ -4 = 0,0625

Gleitkomma-Binärdarstellung:

Vorzeichen Exponentenbruch (ich denke, unsichtbar 1 wird an den Bruch angehängt)
B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0


0

Die Antwort mit der höchsten Punktzahl hat es geschafft.

Zuerst haben Sie Basis 2 und Basis 10 in Ihrer Frage gemischt. Wenn Sie dann eine Zahl auf die rechte Seite setzen, die nicht in die Basis teilbar ist, treten Probleme auf. Wie 1/3 in Dezimalzahl, weil 3 nicht in eine Potenz von 10 oder 1/5 in Binärform geht, was nicht in eine Potenz von 2 geht.

Ein weiterer Kommentar, obwohl NIEMALS gleich mit Gleitkommazahlen, Punkt. Selbst wenn es sich um eine exakte Darstellung handelt, gibt es in einigen Gleitkommasystemen einige Zahlen, die auf mehr als eine Weise genau dargestellt werden können (IEEE ist diesbezüglich schlecht, es ist zunächst eine schreckliche Gleitkommaspezifikation, also erwarten Sie Kopfschmerzen). Kein Unterschied hier 1/3 ist nicht gleich der Zahl auf Ihrem Rechner 0.3333333, egal wie viele 3en rechts vom Dezimalpunkt stehen. Es ist oder kann nah genug sein, ist aber nicht gleich. Sie würden also erwarten, dass so etwas wie 2 * 1/3 je nach Rundung nicht 2/3 entspricht. Verwenden Sie niemals gleich mit Gleitkomma.


0

Wie wir bereits besprochen haben, kann in der Gleitkomma-Arithmetik die Dezimalzahl 0,1 nicht perfekt binär dargestellt werden.

Gleitkomma- und Ganzzahldarstellungen liefern Gitter oder Gitter für die dargestellten Zahlen. Wenn die Arithmetik durchgeführt wird, fallen die Ergebnisse vom Gitter ab und müssen durch Runden auf das Gitter zurückgesetzt werden. Beispiel ist 1/10 in einem binären Gitter.

Wenn wir eine binär codierte Dezimaldarstellung verwenden, wie es ein Gentleman vorgeschlagen hat, könnten wir dann Zahlen im Raster behalten?


1
Dezimalzahlen, klar. Aber das ist nur per Definition. Sie können nicht 1/3 in Dezimalzahlen darstellen, genauso wenig wie Sie 0,1 in Binärzahlen darstellen können. Jedes Quantisierungsschema schlägt für einen unendlich großen Satz von Zahlen fehl.
Kylotan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.