Float32 zu Float16
Kann mir jemand erklären, wie ich konvertiert eine 32-bit-floating-point-Wert in eine 16-bit-floating-point-Wert?
(s = Vorzeichen e = exponent und m = Mantisse)
Wenn 32-bit float ist 1s7e24m
Und 16-bit-float ist 1s5e10m
Dann ist es so einfach wie zu tun?
int fltInt32;
short fltInt16;
memcpy( &fltInt32, &flt, sizeof( float ) );
fltInt16 = (fltInt32 & 0x00FFFFFF) >> 14;
fltInt16 |= ((fltInt32 & 0x7f000000) >> 26) << 10;
fltInt16 |= ((fltInt32 & 0x80000000) >> 16);
Ich nehme an, es IST gar NICHT so einfach ... also wer kann mir sagen, was Sie TUN müssen, zu tun?
Edit: ich cam sehe, habe ich meine exponent shift falsch ... so wäre DAS besser?
fltInt16 = (fltInt32 & 0x007FFFFF) >> 13;
fltInt16 |= (fltInt32 & 0x7c000000) >> 13;
fltInt16 |= (fltInt32 & 0x80000000) >> 16;
Ich hoffe, dies ist korrekt. Entschuldigt, wenn ich bin fehlt etwas offensichtlich gesagt wurde. Seine fast Mitternacht, an einem Freitag Abend ... also ich bin nicht "ganz" nüchtern 😉
Edit 2: Uuups. Bummelte er wieder. Ich will zu verlieren, die oberen 3 bits, nicht die untere! So wie über diese:
fltInt16 = (fltInt32 & 0x007FFFFF) >> 13;
fltInt16 |= (fltInt32 & 0x0f800000) >> 13;
fltInt16 |= (fltInt32 & 0x80000000) >> 16;
Der endgültige code sollte:
fltInt16 = ((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13);
fltInt16 |= ((fltInt32 & 0x80000000) >> 16);
- Ich glaube das wurde schon gefragt (und beantwortet) hier: stackoverflow.com/questions/1659440/...
- es könnte so einfach sein, aber Sie verlieren Präzision, es sei denn, float32 nicht verwenden Sie alle "Präzision" hat... im Prinzip hat man 5/7 bits exp (Sie nehmen natürlich die meisten bedeutungsvollen) und 10/24 der Mantisse; diese Verhältnisse sagen irgendwie, wie viel Sie verlieren können in der Konvertierung. genau so, wie es passiert, wenn Sie nicht wollen, um fit 32-bit ganze Zahl in eine 16 bit integer... die Palette der rappresentable Nummern kleiner ist; "schneiden" der Mantisse reduziert die "Präzision", und der exponent auch die Grenzen der Reichweite: 5 signierten bits geben -16 bis +15, gegen -64/+63 (wenn ich es Recht...:D es ist spät)
- Sicher ist es nicht möglich zu verlieren 16-bit-Daten NICHT zu verlieren und die Präzision?? Float16 ist weit weniger präzise und damit automatisch weniger Präzision ... oder bin ich Missverständnis Sie?
- Sie können Locker 16 bit und habe das "float16", die die "exakt" gleiche Anzahl von float32, einfach Sie zu "wählen", die float32-Nummer, so dass es passiert ist... aber normalerweise kann man nicht wählen, so dass die meisten der Zeit, was passiert ist zu verlieren Informationen. Anders gesagt, Sie passen in float32 alle float16 Anzahl (vorausgesetzt, die gleichen Konventionen) und mit "return" wieder zurück zu float16 verlieren nichts (f16 > f32 nicht "erfinden" "Präzision," und so f16 > f32 > f16' getan werden kann, so dass die f16' === f16)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Exponenten in Ihrer float32 und float16 Darstellungen sind vermutlich parteiisch und voreingenommen anders. Sie müssen unbias der exponent, die Sie von der float32-Darstellung, um die tatsächliche exponent, und klicken Sie dann auf bias es für die float16 Darstellung.
Abgesehen von diesem detail, ich denke, es ist so einfach, aber ich bekomme immer noch überrascht von Fließkomma-Darstellungen, die von Zeit zu Zeit.
EDIT:
Check für überlauf, wenn dabei die Sache mit dem Exponenten, während Sie gerade dabei sind.
Ihren Algorithmus schneidet die letzten bits der mantisa ein wenig abrupt, das kann akzeptabel sein, aber möchten Sie vielleicht zu implementieren, zu sagen, round-to-nearest indem man die bits, die über verworfen werden. "0..." -> hin down, "100..001..." -> round up", 100..00" -> hin zu selbst.
Der exponent muss unvoreingenommen sein, eingespannt und rebiased. Dies ist der schnelle code, den ich verwenden:
Dieser code sogar noch schneller mit einer lookup-Tabelle für den Exponenten, aber ich benutze diese, weil es leicht angepasst werden, um eine SIMD-workflow.
Grenzen der Umsetzung:
2^-15
und2^-14
anstelle von null.Vorsichtig sein mit denormals. Wenn Ihre Architektur verwendet, Sie können Ihr Programm verlangsamen enorm.
Hier ist der link zu einem Artikel auf IEEE754, was gibt die bit-layouts und Neigungen.
http://en.wikipedia.org/wiki/IEEE_754-2008