Die Konvertierung von float.hex () - Wert zu binary in Python
Frage ich mich, wie konvertiert man das Ergebnis von float.hex()
binären, zum Beispiel von 0x1.a000000000000p+2
zu 110.1
.
Kann bitte jemand helfen? Danke.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erklärung:
float.fromhex
gibt einen floatnum
. Wir würden gerne eine Binär-Repräsentation.{0:b}.format(...)
gibt binären Darstellungen von zahlen, aber nicht schwimmt.Aber wenn wir multiplizieren Sie die Schwimmer genug von Potenzen von 2, das heißt, eine Verschiebung der binären Darstellung auf der linken Seite genug Platz, wir am Ende mit einem integer,
shifted_num
.Einmal haben wir die ganze Zahl ist, sind wir frei Haus, denn nun können wir
{0:b}.format(...)
.Können wir re-legen Sie die Punkttaste (err, binäre Punkt?) durch die Verwendung eines bit-string-slicing-basiert auf der Anzahl der Orte, die wir hatten, die nach Links verschoben ist (
exponent
).Technischen Punkt: Die Anzahl der Ziffern in der binären Darstellung der
shifted_num
kleiner sein kann alsexponent
. In diesem Fall müssen wir ein pad die binäre Darstellung mit mehr 0 ist auf der linken Seite, also binäre schneiden mitbinary[:-exponent]
nicht leer ist. Wir verwalten, die mit'{0:0{1}b}'.format(...)
. Die0{1}
im format-string legt die Breite des formatierten string zu{1}
auf der linken Seite aufgefüllt mit Nullen. (Die{1}
wird ersetzt durch die Anzahlexponent
.)if exponent==0:
, jetzt ist es völlig korrekt; vor, dass, ohne diese Bedingung, wird Ihr code gab seltsame Ergebnisse für big-big-zahlen. Jetzt funktioniert es perfectylyif pdec-tin==0:
. !! Offensichtlich war, könnte es löst Probleme!!!!if pdec-tin==0:
selbst das problem verursacht. Wie ich schon in meiner Bearbeitung beantworten, es gibt jetzt eine Anleitunga,_,p = '{:f}'.format(fromh).partition('.')
Aber , da bin ich mir nicht so viel geübt mit format() , ist die Tatsache, dass das Muster ist einfach {:f} macht, dass der resultierende string ist beschränkt in der Präzision, die wohl standardmäßig. Also, wenn ich an die Zahl x = 780.2265625, die daraus resultierenden h = x.hex() == '0 x 1.861d000000000p+9' und dann float.fromhex(h) == 780.2265625, das ist richtig, .....if pdec-tin==0:
wurde nie respektiert, auch wenn pdec und zinn Decimal-Instanzen und-bits Hinzugefügt wurden, mehr als die, die notwendig zur Darstellung des 780.2265625. Ich brauche etwas wie, dassa,_,p = '{:.15f}'.format(fromh).partition('.')
um das problem zu beheben, und jetzt ist mein code geben genau die gleichen Ergebnisse wie Ihr. Ouf !Hinweis, dass die binäre form
0x1.a000000000000p+2
ist nicht101.1
(oder genauer0b101.1
)aber
0b110.1
(in meinem Python 2.7, binäre zahlen dargestellt werden wie die).
Ersten, eine nützliche Methode der float-Instanzen
float.hex()
und seine inverse-Funktion, die einen float-Methode der Klassefloat.fromhex()
Ergebnis
"Beachten Sie, dass float.hex() ist eine Instanzmethode, während schweben.fromhex() ist eine Methode der Klasse."
http://docs.python.org/library/stdtypes.html#float.fromhex
.
Zweitens, ich habe nicht eine Python-Funktion zu transformieren, eine hexadezimale Darstellung einer float in eine binäre Darstellung dieses schweben, das heißt mit einem Punkt ( noch als einen direkt zu verwandeln, eine dezimal-Darstellung einer float in eine binäre eins).
So habe ich eine Funktion für diesen Zweck.
Vor der hand, diese Funktion wandelt die hexadezimale Darstellung in eine dezimale Darstellung (string) die Eingabe von float.
Dann gibt es zwei Probleme:
how, um den Teil vor dem Punkt ?
Dieser Teil ist eine ganze Zahl, es ist einfach zu bedienen
bin()
how, um den Teil nach dem Punkt ??
Das problem dieser transformation wurde schon mehrfach gefragt, auf SO, aber ich Verstand nicht, die Lösungen, so schrieb ich meine eigene.
Dann, hier ist die Funktion, die Sie möchten, Qiang Li:
.
Zur Durchführung der Verifizierung, schrieb ich eine Funktion zu verwandeln, die Teil einer Binär float nach einem Punkt in seine dezimale Darstellung:
.
.
Schließlich, die Anwendung dieser Funktionen:
Ergebnis
.
Für die zwei zahlen:
als ein Ergebnis, das zeigt:
Gegeben, die eine hexadezimale Zeichenfolge
h
finden Sie die entsprechenden float mitAlso wirklich, du bist interessant, in der Lage zu produzieren, einen "festen Punkt" binäre Darstellung einer float. Seine möglich, es gibt keine endliche Darstellung, so dass Sie wahrscheinlich wollen, beschränken Sie die Länge es sein kann. (z.B. die binäre Darstellung der Mathematik.pi würde nicht zu Ende ...)
So etwas wie das folgende funktionieren könnte
ValueError: invalid literal for int() with base 10: '0x1.a000000000000p+2'
Dann legte ichx = float.fromhex(h)
in der Funktion am Anfang (und ersetzen den parameter w mit h) und dann das Programm ausgeführt; es ergab sich : 11.11011 und 11.11011. Ja, das gleiche. Führen Sie einen code vor der Veröffentlichung.So really you're interesting in being able to produce a "fixed point" binary representation of any float
und die Funktion macht genau das. Warum eine Funktion schreiben, die nur wandelt hex in Binär-als eine, die konvertiert schwimmt auf binäre ist weitaus nützlicher. WeiterebinaryRepresentation(float.fromhex('0x1.a000000000000p+2'))
undbinaryRepresentation(float.fromhex('0x1.b5c2000000000p+1'))
produzieren 110.1 und 11.11011 beziehungsweise. Ja nicht die gleiche. Sie sollten Lesen, ein posting richtig, bevor Sie kommentieren es.x = float.fromhex(h)
und ich dachte, ersetzen Sie den parameter x Ihrer Funktion mit dem parameter h , aber ich muss es getestet haben, haben den gleichen Wert als argument sicherlich der Grund, warum ich erhielt zwei mal den gleichen Wert 11.11011 ; tut mir Leid.Großen BEARBEITEN über die großen zahlen
.
Der folgende code zeigt ein problem mit meiner Lösung in meiner anderen Antwort.
Beachten Sie, dass ich verändert die parameter meiner Funktion hexf2binf(floathex) von h zu floathex zu machen, die selben wie der parameter verwendet, von unutbu in seiner Funktion floathex_to_binary(floathex)
Ergebnis
Ist das problem durch die Anweisung
str(float.fromhex(x))
im Unterrichta,_,p = str(float.fromhex(x)).partition('.')
produziert , für eine große Zahl, eine Darstellung der schweben.fromhex(x) mit einem Exponenten.Anschließend werden DIE TEILE VOR DEM PUNKT (a ante) UND NACH DEM PUNKT (p (post) FALSCH.
Korrektur ist einfach: ersetzen der ungenauen Anweisung hinzu:
.
Nota bene:
Dass bedeutet, dass, wenn ein großer Wert für ein float ist geschrieben in einem code, dessen interne Repräsentation ist in der Tat eine Annäherung der geschriebenen Wert.
Das ist dargestellt durch den folgenden code:
Ergebnis
Werte h1 und h2 sind die gleichen, weil Sie zwar verschiedene Werte zugewiesen Bezeichner x1 und x2 in das Skript, das OBJEKTE x1 und x2 vertreten sind, mit der gleichen Näherung in der Maschine.
Die interne Darstellung von 123456789012345685803008.0 ist der genaue Wert von 123456789012345685803008.0 und ist die interne Darstellung von 123456789012345678901234.64655 aber seine Annäherung, daher der Abzug von h1 und h2 von x1 und x2 gibt den gleichen Wert zu h1 und h2.
Dieses problem existiert, wenn wir schreiben eine Zahl in Dezimaldarstellung in einem Skript. Es existiert nicht, wenn wir schreiben direkt eine Nummer in hexadezimaler oder binärer Darstellung.
, Was ich wollte, zu betonen
ist, dass ich schrieb eine Funktion afterdotbinary2float(sbin, com = com) durchführen Prüfung auf den Ergebnissen hexf2binf( ). Diese überprüfung funktioniert gut, wenn die Anzahl übergeben hexf2binf( ) ist nicht groß, aber wegen der internen Angleichung von großen zahlen (= mit einer Menge von Ziffern), Frage ich mich, ob diese überprüfung nicht verdreht ist. In der Tat, wenn eine große Anzahl kommt in der Funktion, es wurde bereits angenähert : die Ziffern nach dem Punkt umgewandelt worden in eine Reihe von Nullen;
wie hier gezeigt nach:
Ergebnis
Fazit: ein Test mit zahlen 123456789012345685803008.0 und 123456789012345678901234.64655 keinen Unterschied macht und kein Interesse.
So, ich wollte testen, un-zahlen approximiert, und ich ging einen Decimal-float-Zahl. Wie Sie sehen, das problem ist, dass eine solche Instanz noch nicht die hex() Methode.
.
Endlich, ich bin nicht ganz sicher, meine Funktion für die großen zahlen, aber es funktioniert richtig für die gemeinsamen zahlen haben, nachdem ich Sie korrigiert die falsche Anweisung.
.
BEARBEITEN
Ich fügte hinzu, '.400' in die Anweisung:
andernfalls wird der Wert von p könnte abgeschnitten werden, so dass eine binäre Darstellung eine etwas andere Nummer als die, die an die Funktion übergeben.
Legte ich 400, weil es die Länge, die ich definiert für die Liste tinies enthält die Dezimal-Instanzen, entsprechend 1/2 , 1/4 , 1/8 , 1/16 etc
Jedoch, obwohl es ist selten, dass eine Zahl mit mehr als 400 stellen nach dem Komma hat keinen Sinn, das hinzufügen unbefriedigend bleibt für mich: der code ist nicht absolut Allgemeine, ist der Fall von unutbu 's code.