Hier ist der Schlüssel zu Ihrem Dilemma: 10
ist das Produkt von 2
und 5
. Sie können beliebig viele genau in der Basis 10 Dezimalzahlen darstellen , die k * 1/2 n * 1/5 m , wo k
, n
und m
ganze Zahlen sind.
Alternativ formuliert - Wenn die Zahl n
in 1 / n einen Faktor enthält, der nicht Teil der Faktoren der Basis ist, kann die Zahl in der binären / dezimalen / beliebigen Erweiterung nicht genau mit einer festen Anzahl von Ziffern dargestellt werden number - es wird einen sich wiederholenden Teil haben. Zum Beispiel 1/15 = 0.0666666666 .... weil 3 (15 = 3 * 5) kein Faktor von 10 ist.
Somit kann alles, was in der Basis 2 genau dargestellt werden kann (k · 1/2 n ), in der Basis 10 genau dargestellt werden.
Darüber hinaus gibt es die Frage, wie viele Stellen / Bits Sie zur Darstellung der Zahl verwenden. Es gibt einige Zahlen, die in einer Basis exakt dargestellt werden können, aber es sind mehr als einige Ziffern / Bits erforderlich, um dies zu tun.
In der Binärdarstellung kann die Zahl 1/10, die günstigerweise 0,1 dezimal ist, nicht als Zahl dargestellt werden, die in einer festen Anzahl von Bits in der Binärdarstellung dargestellt werden kann. Stattdessen lautet die Nummer 0.00011001100110011 ... 2 (wobei sich der 0011-Teil für immer wiederholt).
Lets Blick auf der Nummer 1 2 /1010 2 einen engen Bit.
____
0,00011
+ ---------
1010 | 1.00000
0
-
1 0
0
----
1 00 --------- +
0 |
----- |
1 000 |
0 |
------ | wiederholen
1 0000 | Block
1010 |
------ |
1100 |
1010 |
---- |
100 ---- +
Dies ist genau die gleiche Art von Dingen, die Sie erhalten, wenn Sie versuchen, die lange Division für 1/3 durchzuführen.
1/10, wenn berücksichtigt, ist 1 / (2 1 * 5 1 ). Für die Basis 10 (oder ein Vielfaches von 10) endet diese Nummer und wird als reguläre Nummer bezeichnet . Eine sich wiederholende Dezimalerweiterung wird als sich wiederholende Dezimalzahl bezeichnet , und diese Zahlen, die für immer ohne Wiederholung weitergehen, sind irrationale Zahlen.
Die Mathematik dahinter befasst sich mit Fermats kleinem Theorem ... und sobald Sie anfangen, Fermat oder Theorem zu sagen, wird es zu einer Math.SE-Frage .
Gibt es Zahlen, die in der Basis 10 nicht darstellbar sind, aber in der Basis 2 dargestellt werden können?
Die Antwort ist nein'.
An dieser Stelle sollte uns allen klar sein, dass jede binäre Expansion einer rationalen Zahl mit fester Länge als dezimale Expansion mit fester Länge dargestellt werden kann.
Lets Blick stärker auf das Dezimalsystem in C # , die uns führt Gleitpunktberechnungen in .NET und den Autor gegeben, werde ich , dass das ist , akzeptieren , wie es funktioniert.
Der Dezimaltyp hat die gleichen Komponenten wie jede andere Gleitkommazahl: eine Mantisse, einen Exponenten und ein Vorzeichen. Wie üblich ist das Vorzeichen nur ein einzelnes Bit, aber es gibt 96 Bits Mantisse und 5 Bits Exponent. Es sind jedoch nicht alle Exponentenkombinationen gültig. Es funktionieren nur die Werte 0-28, und sie sind praktisch alle negativ: Der numerische Wert ist . Dies bedeutet, dass die Maximal- und Minimalwerte des Typs +/- (2 96 -1) sind und die kleinste Zahl ungleich Null, ausgedrückt als absolute Größe, 10 -28 beträgt .sign * mantissa / 10exponent
Ich werde gleich darauf hinweisen, dass es aufgrund dieser Implementierung Zahlen in dem double
Typ gibt, die nicht dargestellt werden können decimal
- solche, die außerhalb des Bereichs liegen. Double.Epsilon
ist , 4.94065645841247e-324
die in einem nicht dargestellt werden können decimal
, sondern in einem double
.
Innerhalb des Bereichs, den die Dezimalzahl darstellen kann, hat sie jedoch eine höhere Genauigkeit als andere native Typen und kann sie fehlerfrei darstellen.
Es gibt einige andere Typen, die herumschweben. In C # gibt es eine BigInteger- Zahl, die eine beliebig große Ganzzahl darstellen kann. Es gibt kein Äquivalent zu Java BigDecimal (die Zahlen nach oben mit Dezimalstellen von bis zu 2 darstellen kann 32 Ziffern lang - das ist eine beträchtliche Reichweite ist) genau . Wenn Sie jedoch ein wenig herumstöbern, finden Sie handgerollte Implementierungen.
Es gibt einige Sprachen, die auch einen rationalen Datentyp haben , mit dem Sie Rationales genau darstellen können (so dass 1/3 tatsächlich 1/3 ist).
Speziell für C # und die Wahl zwischen Float und Rational werde ich mich von dem Pint Decimal Floating in .NET an Jon Skeet wenden :
Die meisten Geschäftsanwendungen sollten wahrscheinlich dezimal statt float oder double verwenden. Meine Faustregel ist, dass künstliche Werte wie die Währung normalerweise besser mit Dezimal-Fließkomma dargestellt werden: Das Konzept von genau 1,25 Dollar ist zum Beispiel völlig vernünftig. Bei Werten aus der Natur wie Längen und Gewichten sind binäre Gleitkommatypen sinnvoller. Obwohl es theoretisch "genau 1,25 Meter" gibt, wird es in der Realität nie vorkommen: Sie werden mit Sicherheit nie in der Lage sein, exakte Längen zu messen, und es ist unwahrscheinlich, dass sie überhaupt auf atomarer Ebene existieren. Wir sind daran gewöhnt, dass es um eine gewisse Toleranz geht.