Hat ein Float 32 Binärziffern und ein Doppel 64 Binärziffern? Die Dokumentation war zu schwer zu verstehen.
Werden alle Bits in signifikante Ziffern übersetzt? Oder nimmt die Position des Dezimalpunkts einige der Bits ein?
Hat ein Float 32 Binärziffern und ein Doppel 64 Binärziffern? Die Dokumentation war zu schwer zu verstehen.
Werden alle Bits in signifikante Ziffern übersetzt? Oder nimmt die Position des Dezimalpunkts einige der Bits ein?
Antworten:
float : 32 Bit (4 Byte), wobei 23 Bit für die Mantisse verwendet werden (ca. 7 Dezimalstellen). Für den Exponenten werden 8 Bits verwendet, sodass ein Gleitkomma den Dezimalpunkt mit diesen 8 Bits nach rechts oder links „verschieben“ kann. Auf diese Weise wird vermieden, dass viele Nullen in der Mantisse wie in 0,0000003 (3 × 10 -7 ) oder 3000000 (3 × 10 7 ) gespeichert werden . Es wird 1 Bit als Vorzeichenbit verwendet.
double : 64 Bit (8 Byte), wobei 52 Bit für die Mantisse verwendet werden (ca. 16 Dezimalstellen). Für den Exponenten werden 11 Bits verwendet, und 1 Bit ist das Vorzeichenbit.
Da wir binär verwenden (nur 0 und 1), ist ein Bit in der Mantisse implizit 1 (sowohl float als auch double verwenden diesen Trick), wenn die Zahl nicht Null ist.
Da alles binär ist (Mantisse und Exponenten), sind die Umrechnungen in Dezimalzahlen normalerweise nicht genau. Zahlen wie 0,5, 0,25, 0,75, 0,125 werden genau gespeichert, 0,1 jedoch nicht. Wie andere bereits gesagt haben, verwenden Sie nicht float oder double, sondern int, long, BigInteger oder BigDecimal, wenn Sie Cent genau speichern müssen.
Quellen:
http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers
double
und 7,2 für float
, dh 15 und 7. Es können jeweils einige größere Zahlen dargestellt werden, und keine davon gilt für Brüche, aber es gibt keinen "Durchschnitt", und keine Ihrer Quellen sagt dies aus Andernfalls.
Lange Antwort:
Gleitkommazahlen bestehen aus drei Komponenten:
Im Wesentlichen funktioniert dies zu sign * 2^exponent * (1 + fraction)
. Die „Größe“ der Zahl, ihr Exponent, ist für uns irrelevant, da sie nur den Wert des Bruchteils skaliert . Wenn wir wissen, dass dies log₁₀(n)
die Anzahl der Ziffern von n
† ergibt, können wir die Genauigkeit einer Gleitkommazahl mit bestimmen log₁₀(largest_possible_fraction)
. Da jedes Bit in einem Float zwei Möglichkeiten speichert, kann eine binäre Anzahl von n
Bits eine Zahl bis zu speichern 2ⁿ - 1
(insgesamt 2ⁿ
Werte, bei denen einer der Werte Null ist). Dies wird etwas haariger, da sich herausstellt, dass Gleitkommazahlen mit einem Bruchteil weniger gespeichert werden, als sie verwenden können, da Nullen speziell dargestellt werden und alle Nicht-Null-Zahlen mindestens ein Nicht-Null-Binärbit haben. ‡
In Kombination ergibt sich die Genauigkeit für eine Gleitkommazahl
log₁₀(2ⁿ)
, wobei n
die Anzahl der Bits des Bruchteils der Gleitkommazahl ist. Ein 32-Bit-Float hat 24 Bruchbits für eine Genauigkeit von 7,22 Dezimalstellen, und ein 64-Bit-Doppel hat 53 Bruchstellen für eine Genauigkeit von 15,95 Dezimalstellen.
Weitere Informationen zur Gleitkomma-Genauigkeit finden Sie im Konzept eines Maschinen-Epsilons .
† n ≥ 1
Zumindest für andere Zahlen sieht Ihre Formel eher so aus
⌊log₁₀(|n|)⌋ + 1
.
‡ „Diese Regel wird verschiedentlich als Leitbitkonvention, implizite Bitkonvention oder Hidden-Bit-Konvention bezeichnet.“ ( Wikipedia )
Aus der Java-Spezifikation :
Die Gleitkommatypen sind Gleitkomma- und Doppeltypen, die konzeptionell mit den IEEE 754-Werten und -Operationen im 32-Bit- und 64-Bit-Format mit einfacher Genauigkeit gemäß IEEE-Standard für binäre Gleitkomma-Arithmetik, ANSI / IEEE, verknüpft sind Standard 754-1985 (IEEE, New York).
Da es schwierig ist, mit Zahlen etwas zu tun, ohne die Grundlagen von IEEE754 zu verstehen, finden Sie hier einen weiteren Link .
Es ist wichtig zu verstehen, dass die Genauigkeit nicht einheitlich ist und dass dies keine exakte Speicherung der Zahlen ist, wie dies für ganze Zahlen der Fall ist.
Ein Beispiel :
double a = 0.3 - 0.1;
System.out.println(a);
druckt
0.19999999999999998
Wenn Sie eine willkürliche Genauigkeit benötigen (zum Beispiel für finanzielle Zwecke), benötigen Sie möglicherweise Big Decimal .
Eine normale mathematische Antwort.
Wenn man versteht, dass eine Gleitkommazahl als einige Bits implementiert ist, die den Exponenten und den Rest darstellen, meistens für die Ziffern (im Binärsystem), hat man die folgende Situation:
Bei einem hohen Exponenten, beispielsweise 10²³, erscheint ein großer Unterschied zwischen zwei benachbarten unterscheidbaren Zahlen, wenn das niedrigstwertige Bit geändert wird. Darüber hinaus bewirkt der Dezimalpunkt der Basis 2, dass viele Zahlen der Basis 10 nur angenähert werden können. 1/5, 1/10 sind endlose Zahlen.
Im Allgemeinen sollten Gleitkommazahlen nicht verwendet werden, wenn Sie sich für signifikante Ziffern interessieren. Verwenden Sie für Geldbeträge mit Berechnung am besten BigDecimal .
Für die Physik sind Gleitkomma- Doppel ausreichend, schwebt fast nie. Darüber hinaus kann der Gleitkommateil von Prozessoren, die FPU, intern sogar etwas mehr Präzision verwenden.
Gleitkommazahlen werden mit einer Exponentialform codiert, das heißt so etwas m * b ^ e
wie Ganzzahlen überhaupt nicht. Die Frage, die Sie stellen, wäre im Zusammenhang mit Festkommazahlen sinnvoll . Es stehen zahlreiche Festpunkt-Arithmetikbibliotheken zur Verfügung.
In Bezug auf Gleitkomma-Arithmetik: Die Anzahl der Dezimalstellen hängt von der Darstellung und dem Zahlensystem ab. Zum Beispiel gibt es periodische Zahlen ( 0.33333
), die keine endliche Darstellung in Dezimalzahl haben, sondern eine in Binärzahl und umgekehrt.
Erwähnenswert ist auch, dass Gleitkommazahlen bis zu einem bestimmten Punkt einen Unterschied von mehr als eins aufweisen, dh value + 1
Ausbeuten value
, da value + 1
sie nicht mit m * b ^ e
where codiert werden m
können b
und e
in der Länge festgelegt sind. Gleiches gilt für Werte kleiner als 1, dh alle möglichen Codepunkte haben nicht den gleichen Abstand.
Aus diesem Grund gibt es keine Genauigkeit von exakten n
Ziffern wie bei Festkommazahlen, da nicht jede Zahl mit n
Dezimalstellen eine IEEE-Codierung hat.
Es gibt ein fast obligatorisches Dokument, das Sie dann lesen sollten und das Gleitkommazahlen erklärt: Was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte .
Schauen Sie sich an Float.intBitsToFloat
und Double.longBitsToDouble
, welche Art von Erklärung, wie Bits Gleitkommazahlen entsprechen. Insbesondere sehen die Teile eines Normalen float
ungefähr so aus
s * 2^exp * 1.ABCDEFGHIJKLMNOPQRSTUVW
Dabei sind A ... W 23 Bits - 0s und 1s -, die einen Bruch in Binärform darstellen - s ist +/- 1, dargestellt durch eine 0 bzw. eine 1, und exp ist eine vorzeichenbehaftete 8-Bit-Ganzzahl.