Ja. 32-Bit-Ganzzahlen können genau als 64-Bit-Gleitkommazahlen dargestellt werden.
Ich habe Visual Studio geöffnet und getestet.
Hier ist mein Code:
%Vor%Das Ergebnis waren zwei Messageboxen, die "true" sagten.
Ich schätze, das kommt zu dem Schluss: Ja, Sie werden garantiert, dass es wahr sein wird.
EDIT: Habe meinen Test etwas verlängert. Der einzige Test, der falsch zurücklief, war der Test bei double.MaxValue, aber ich bezweifle, dass Sie diese großen Zahlen verwenden werden.
Ja, Sie können eine (32-Bit-) Ganzzahl in a == b
(64-Bit-Gleitkommazahl) ohne Präzisionsverlust speichern.
Sobald Sie jedoch Berechnungen mit Ihrem %code% durchführen, werden Sie sehr wahrscheinlich Rundungsfehler, d. h. Präzisionsverlust, einführen. Diese Fehler sind wahrscheinlich klein genug, sodass sie weggerundet werden, wenn Sie Ihren %code% -Wert wieder auf %code% setzen - aber der Fehler ist dort, also beachten Sie es.
Wie es gemacht wird: Siehe dieses Dokument ( IEEE Standard 754 Fließkommazahlen von Steve Hollasch für Details darüber, wie eine ganze Zahl als Gleitkommawert gespeichert werden kann.
Um (etwas ungenau) zusammenzufassen, besteht ein Fließkommawert aus drei Teilen: Ein Vorzeichenbit, ein "Bruch" -Teil (Mantisse genannt) und ein "Exponent" -Teil. Sie sind grob wie folgt zusammengesetzt:
Wert = -1 Vorzeichenbit × Bruch × 2 Exponent
Sie können den ganzzahligen Wert im "fraction" -Teil von %code% speichern (was 52 Bits breit ist, was mehr als breit genug für eine 32-Bit-Ganzzahl ist. Der "Exponent" -Teil kann einfach auf gesetzt werden 0, da es nicht benötigt wird.
Ist sichergestellt, dass a == b wahr ist?
Ja. Dies liegt daran, dass Sie die gleiche Konvertierung zweimal durchführen und aufgrund ihres deterministischen Verhaltens die gleichen Werte erhalten, unabhängig von den Rundungsproblemen.
Wir können jedoch Ihre Frage verallgemeinern:
Können wir arithmetische Operationen an 32-Bit-Integer-Werten ausführen, die in %code% type ohne Genauigkeit loose codiert sind?
Die Antwort auf eine solche Frage lautet ja auch.
Eine kurze Begründung ist, dass Operationen auf Mantissen-Bits (siehe Ссылка ) genau sind, wenn es nur möglich ist und im Fall von 32-Bit-Integer-Werten ist es möglich.
Längere Geschichte kommt hier. Solange Ihr Integer-Wert in 52 Bits eines Fraktionsteils mit der Bezeichnung Mantisse passt (siehe Ссылка ), werden alle Berechnungen für ganzzahlige Werte mit double verhält sich vollständig OK.
Dies liegt daran, dass Ihre Zahl (zB 173, die %code% binary ist) als %code% dargestellt wird, was genau ist.
Alle Operationen auf Mantisse sind einfach, solange sie in die Mantisse passen. Rundungen auf Ganzzahlen treten auf, wenn das Ergebnis einer bestimmten Operation nicht in die Mantisse passt - z. Sie würden 40 Bits Mantisse mit 40 Bits Mantisse multiplizieren. Das Runden von Gleitkommaoperationen tritt zusätzlich auf, wenn Exponenten sehr unterschiedlich sind. In diesem Fall kann sogar eine einfache Additionsoperation die Präzision verlieren, weil Matinsas verschoben werden.
Zurück zu Ganzzahlen, die im Double-even-Division-Verfahren codiert sind, ist präzise, solange das Ergebnis ein Integer-Wert ist. Also ist %code% auch garantiert wahr.
Das Problem beginnt, wenn Ihre Nummer keine Ganzzahl ist. Aber auch in diesem Fall werden Zahlen garantiert dargestellt, wenn sie eine Form von %code% und %code% in 52 Bits darstellen (zB %code% %code% %code% ). Operationen auf solchen Zahlen sind auch präzise, da %code% für beide Operanden gleich sein kann, also gerade:
%Vor%ist garantiert wahr.
Interessant ist, dass Sie Operationen mit 54-Bit-Ganzzahlen mit Vorzeichen sicher ausführen können. Dies liegt daran, dass Sie am Anfang ein zusätzliches Bit haben, dessen Bedeutung durch den Exponenten und ein zusätzliches Bit für ein Zeichen kodiert wird. Nun -2 ^ 53, was MIN_INT im Falle einer 54 Bit signierten Ganzzahl nicht zur Mantisse passen würde, aber der Exponent wird hier die Aufgabe übernehmen mit Mantisse voller Nullen.
Ist sichergestellt, dass a == b wahr ist?
Ja. Dies liegt daran, dass Sie die gleiche Konvertierung zweimal durchführen und aufgrund ihres deterministischen Verhaltens die gleichen Werte erhalten, unabhängig von den Rundungsproblemen.
Wir können jedoch Ihre Frage verallgemeinern:
Können wir arithmetische Operationen an 32-Bit-Integer-Werten ausführen, die in
double
type ohne Genauigkeit loose codiert sind?
Die Antwort auf eine solche Frage lautet ja auch.
Eine kurze Begründung ist, dass Operationen auf Mantissen-Bits (siehe Ссылка ) genau sind, wenn es nur möglich ist und im Fall von 32-Bit-Integer-Werten ist es möglich.
Längere Geschichte kommt hier. Solange Ihr Integer-Wert in 52 Bits eines Fraktionsteils mit der Bezeichnung Mantisse passt (siehe Ссылка ), werden alle Berechnungen für ganzzahlige Werte mit double verhält sich vollständig OK.
Dies liegt daran, dass Ihre Zahl (zB 173, die 0000010101101b
binary ist) als 1.010110100000b*2^7
dargestellt wird, was genau ist.
Alle Operationen auf Mantisse sind einfach, solange sie in die Mantisse passen. Rundungen auf Ganzzahlen treten auf, wenn das Ergebnis einer bestimmten Operation nicht in die Mantisse passt - z. Sie würden 40 Bits Mantisse mit 40 Bits Mantisse multiplizieren. Das Runden von Gleitkommaoperationen tritt zusätzlich auf, wenn Exponenten sehr unterschiedlich sind. In diesem Fall kann sogar eine einfache Additionsoperation die Präzision verlieren, weil Matinsas verschoben werden.
Zurück zu Ganzzahlen, die im Double-even-Division-Verfahren codiert sind, ist präzise, solange das Ergebnis ein Integer-Wert ist. Also ist 4.0/2.0 == 8.0/4.0
auch garantiert wahr.
Das Problem beginnt, wenn Ihre Nummer keine Ganzzahl ist. Aber auch in diesem Fall werden Zahlen garantiert dargestellt, wenn sie eine Form von x/2^y
und x
in 52 Bits darstellen (zB 3/4
5/8
345/1024
). Operationen auf solchen Zahlen sind auch präzise, da y
für beide Operanden gleich sein kann, also gerade:
ist garantiert wahr.
Interessant ist, dass Sie Operationen mit 54-Bit-Ganzzahlen mit Vorzeichen sicher ausführen können. Dies liegt daran, dass Sie am Anfang ein zusätzliches Bit haben, dessen Bedeutung durch den Exponenten und ein zusätzliches Bit für ein Zeichen kodiert wird. Nun -2 ^ 53, was MIN_INT im Falle einer 54 Bit signierten Ganzzahl nicht zur Mantisse passen würde, aber der Exponent wird hier die Aufgabe übernehmen mit Mantisse voller Nullen.
Ja, Sie können eine (32-Bit-) Ganzzahl in double
(64-Bit-Gleitkommazahl) ohne Präzisionsverlust speichern.
Sobald Sie jedoch Berechnungen mit Ihrem double
durchführen, werden Sie sehr wahrscheinlich Rundungsfehler, d. h. Präzisionsverlust, einführen. Diese Fehler sind wahrscheinlich klein genug, sodass sie weggerundet werden, wenn Sie Ihren double
-Wert wieder auf int
setzen - aber der Fehler ist dort, also beachten Sie es.
Wie es gemacht wird: Siehe dieses Dokument ( IEEE Standard 754 Fließkommazahlen von Steve Hollasch für Details darüber, wie eine ganze Zahl als Gleitkommawert gespeichert werden kann.
Um (etwas ungenau) zusammenzufassen, besteht ein Fließkommawert aus drei Teilen: Ein Vorzeichenbit, ein "Bruch" -Teil (Mantisse genannt) und ein "Exponent" -Teil. Sie sind grob wie folgt zusammengesetzt:
Wert = -1 Vorzeichenbit × Bruch × 2 Exponent
Sie können den ganzzahligen Wert im "fraction" -Teil von double
speichern (was 52 Bits breit ist, was mehr als breit genug für eine 32-Bit-Ganzzahl ist. Der "Exponent" -Teil kann einfach auf gesetzt werden 0, da es nicht benötigt wird.
Ich habe Visual Studio geöffnet und getestet.
Hier ist mein Code:
%Vor%Das Ergebnis waren zwei Messageboxen, die "true" sagten.
Ich schätze, das kommt zu dem Schluss: Ja, Sie werden garantiert, dass es wahr sein wird.
EDIT: Habe meinen Test etwas verlängert. Der einzige Test, der falsch zurücklief, war der Test bei double.MaxValue, aber ich bezweifle, dass Sie diese großen Zahlen verwenden werden.