Wie Sie sich richtig zu normalisieren, eine floating-point-Wert in C++?
Vielleicht verstehe ich nicht die IEEE754-standard, der viel, aber da eine Reihe von floating-point-Werte float
oder double
zum Beispiel :
56.543f 3238.124124f 121.3f ...
sind Sie in der Lage, konvertieren Sie Sie in Werten von 0
zu 1
, so dass Sie zu normalisieren, indem Sie einen entsprechenden gemeinsamen Faktor und zu überlegen, was ist der maximale Wert und der minimale Wert in der Menge.
Nun mein Punkt ist, dass in dieser Verwandlung, ich brauche eine viel höhere Präzision für die Ziel -, die reicht von 0
zu 1
wenn im Vergleich zu der Genauigkeit, die ich brauche, in den ersten ein, vor allem, wenn die Werte in der ersten Reihe sind für ein breites Spektrum von numerischen Werten ( wirklich große und sehr kleine Werte ).
Wie die float
oder die double
( oder die IEEE-754-standard, wenn Sie möchten ) geben kann, mit dieser situation umzugehen, während die Bereitstellung von mehr Präzision für die zweite Gruppe von Werten zu wissen, dass ich im Grunde nicht brauchen einen ganzzahligen Teil ?
Oder er damit nicht zurechtkommt und ich brauche festen Punkt Mathematik mit einem ganz anderen Typ ?
- beachten Sie, dass ieee-floats sind nicht zwingend in c++
- Gibt es compiler, die nicht implementieren IEEE 754? Oder besser gesagt, die modernen CPU-Architekturen nicht umsetzen?
- Es ist normalerweise nicht der compiler, das ist die hardware. Kann ich derzeit denke, ist, VAX.
- SSE-Implementierungen unterstützen FTZ (Flush to zero) und DAZ (Denormals sind null) Optimierungen, die nicht konform zu IEEE 754. Je nach compiler/CRT-dies ist die Standardeinstellung.
- Warum wollen Sie die Karte Werte auf [0, 1]? Wenn Sie möchten, dies zu tun für einige wahrgenommene Präzision Verbesserung, dann tun Sie es nicht, weil es wird nicht gewinnen Sie nichts. Wenn Sie tun es aus einem anderen Grund, dann sollten Sie erklären, dass, so dass wir verstehen können, wie es interagiert mit floating-point-Arithmetik.
- nichts zu tun mit der Wahrnehmung, es geht um die algorithmen, die ich auf diese zahlen und die visuelle Darstellung von Ihnen zu ( die GUI meines Programms ), so dass ich im Grunde muss normalisierte zahlen.
- in diesem Fall bezieht sich nicht auf Fehler, die wahrgenommen werden, die von einem viewer der Daten, sondern durch die Wahrnehmung des Fragestellers, dass es eine Steigerung in der Genauigkeit der Fließkomma-in das Intervall [0, 1] im Vergleich zu einigen anderen im Intervall [0, M].
Du musst angemeldet sein, um einen Kommentar abzugeben.
Floating-point-zahlen sind in einem format gespeichert, wie die wissenschaftliche notation. Intern, so richten Sie die führende
1
von der binären Darstellung an die Spitze der Mantisse. Jeder Wert wird durchgeführt mit der gleichen Anzahl von binären Ziffern für die Genauigkeit in relation zu seiner eigenen Größe.Wenn Sie komprimieren Sie Ihre Satz von floating-point-Werte auf den Bereich 0..1, die nur Präzision Verlust, den Sie erhalten, wird wegen der Rundung, in der die verschiedenen Schritte des Prozesses.
Wenn Sie nur komprimieren, skalieren, verlieren Sie nur eine kleine Menge an Genauigkeit in der Nähe des LSBs der Mantisse (etwa 1 oder 2 ulp, wo ulp bedeutet "Einheiten der letzten Stelle).
Wenn Sie auch zu shift Ihre Daten, dann werden die Dinge komplizierter. Wenn Ihre Daten alle positiv, dann subtrahieren aus der kleinsten Zahl wird nicht nichts beschädigen. Aber, wenn Ihre Daten ist eine Mischung aus positiven und negativen Daten, dann einige Ihrer Werte nahe null leiden kann ein Verlust an Genauigkeit.
Wenn man die Arithmetik auf
double
Präzision, die Sie tragen werden 53 bit Genauigkeit durch die Berechnung. Wenn Ihre Genauigkeit muss passen innerhalb (was Sie wahrscheinlich tun wird), dann wirst du in Ordnung sein. Ansonsten, die genaue numerische Leistung hängt von der Verteilung der Daten.Einzel-und Doppel-IEEE-floats haben ein format, bei dem die Exponenten und Bruch Teile haben Feste bit-Breite. So ist dies nicht möglich (d.h. Sie haben immer die ungenutzten bits, wenn Sie nur zum speichern von Werten zwischen 0 und 1). (Siehe: http://en.wikipedia.org/wiki/Single-precision_floating-point_format)
Sind Sie sicher, dass die 52-bit Breite Bruch Teil eines double nicht genau genug?
Edit: Wenn Sie die ganze Reihe von floating-format, Sie verlieren Präzision bei der Normalisierung der Werte. Die Rundungen können aus sein und genügend kleine Werte werden zu 0. Es sei denn, Sie wissen, dass dies ein problem ist, keine Sorge. Ansonsten muss man suchen, bis eine andere Lösung wie bereits in anderen Antworten.
Wenn Sie haben eine Auswahl von
double
s und Sie zu normalisieren, um zwischen0.0
und1.0
gibt es eine Reihe von Quellen der Präzision Verlust. Sie alle sind aber viel geringer als Sie vermuten.Ersten, werden Sie einige verlieren, Präzision in der arithmetischen Operationen zu normalisieren, Sie als Rundung. Dieser ist relativ klein-ein bisschen oder so pro Betrieb-und in der Regel relativ random.
Zweiten, der exponent Komponente nicht mehr mit dem positiven Exponenten Möglichkeit.
Dritten, so sind alle Werte positiv, das Vorzeichen-bit wird auch verschwendet werden.
Her, wenn die input-Raum nicht enthalten, +inf oder -inf oder +NaN oder -NaN oder dergleichen, diejenigen, die code-Punkte werden auch verschwendet.
Aber zum größten Teil, Sie werden Abfälle über 3 bits von Informationen in einem 64-bit -
double
in Ihrer Normalisierung, von denen die Art der Sache, ist nahezu unumgänglich, wenn Sie sich mit der finite-bit-Breite Werte.Alle 64-bit-fixed-point-Darstellung der Werte von 0 bis 1, wird weit weniger "Auswahl" als
double
s. Eindouble
darstellen kann, etwas in der Größenordnung von10^-300
, während ein 64-bit-fixed-point-Darstellung enthält1.0
nur gehen kann so niedrig wie10^-19
oder so. (Die 64-bit-fixed-point Repräsentation darstellen kann1 - 10^-19
als deutlich vom1
, während diedouble
nicht, aber die 64-bit-fixed-point-Wert kann nicht alles darstellen, kleiner als2^-64
, währenddouble
s kann).Einige der oben genannten zahlen sind Näherungswerte und können abhängig von Runden/genaue format.
Müssen binäre Gleitkommazahlen (mit einer impliziten führenden eine), ausgedrückt als
Einer division a/b ist:
Daher division/Multiplikation hat im wesentlichen ohne Verlust der Präzision.
Einer Subtraktion a-b ist:
Daher eine Subtraktion/Ergänzung möglicherweise ein Verlust an Präzision (groß - klein = groß=) !
Spannen einen Wert x im Bereich [min, max] auf [0, 1]
haben präzise Fragen, ob die Subtraktion hat einen Verlust der Genauigkeit.
Deine Frage zu beantworten:
Nichts ist, wählen Sie eine geeignete Darstellung (floating point, Fraktion, multi Präzision ...) für Ihre algorithmen und den erwarteten Daten.
Für höhere Präzision, die Sie versuchen können,http://www.boost.org/doc/libs/1_55_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats.html.
Beachten Sie auch, dass für die numerische kritischen Operationen +,- gibt es spezielle algorithmen reduzieren die numerischen Fehler durch das Vorgestellte Algorithmus:
http://en.wikipedia.org/wiki/Kahan_summation_algorithm