2010-06-11 3 views
8

क्या कोई मुझे बता सकता है कि मैं 32-बिट फ़्लोटिंग पॉइंट मान को 16-बिट फ़्लोटिंग पॉइंट मान में कैसे परिवर्तित करता हूं?Float32 से Float16

(रों = चिह्न ई = प्रतिपादक और मीटर = अपूर्णांश)

32-बिट नाव 1s7e24m
और 16-बिट नाव है 1s5e10m

है तो यह कर के रूप में सरल है?

int  fltInt32; 
short fltInt16; 
memcpy(&fltInt32, &flt, sizeof(float)); 

fltInt16 = (fltInt32 & 0x00FFFFFF) >> 14; 
fltInt16 |= ((fltInt32 & 0x7f000000) >> 26) << 10; 
fltInt16 |= ((fltInt32 & 0x80000000) >> 16); 

मुझे लगता है कि यह इतना आसान नहीं है ... तो क्या कोई मुझे बता सकता है कि आपको क्या करना है?

संपादित करें: मैं देखता हूं कि मुझे अपना एक्सपोनेंट शिफ्ट गलत मिला है ... तो क्या यह बेहतर होगा?

fltInt16 = (fltInt32 & 0x007FFFFF) >> 13; 
fltInt16 |= (fltInt32 & 0x7c000000) >> 13; 
fltInt16 |= (fltInt32 & 0x80000000) >> 16; 

मुझे उम्मीद है कि यह सही है। क्षमा करें अगर मुझे कुछ स्पष्ट याद आ रही है जो कहा गया है। शुक्रवार की रात को लगभग आधी रात ... इसलिए मैं "पूरी तरह से" शांत नहीं हूं;)

संपादित करें 2: ओउप्स। इसे फिर से खराब कर दिया। मैं शीर्ष 3 बिट्स को कम नहीं करना चाहता हूं! तो कैसे इस बारे में:

fltInt16 = (fltInt32 & 0x007FFFFF) >> 13; 
fltInt16 |= (fltInt32 & 0x0f800000) >> 13; 
fltInt16 |= (fltInt32 & 0x80000000) >> 16; 

अंतिम कोड होना चाहिए:

fltInt16 = ((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13); 
fltInt16 |= ((fltInt32 & 0x80000000) >> 16); 
+2

मुझे लगता है कि यह पहले से ही पूछा गया था (और उत्तर दिया गया): http://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion – humbagumba

+0

यह इतना आसान हो सकता है, लेकिन जब तक फ्लोट 32 अपने सभी "परिशुद्धता" का उपयोग नहीं करता है तब तक आप सटीकता को ढीला करते हैं ... मूल रूप से, आपको एक्सपी के बिट्स का 5/7 मिलता है (आप निश्चित रूप से सबसे महत्वपूर्ण हैं), और मंटिसा के 10/24; इन अनुपातों का कहना है कि रूपांतरण में आप कितना खो सकते हैं। ठीक उसी तरह होता है यदि आप 16 बिट्स पूर्णांक में 32 बिट पूर्णांक फिट करना चाहते हैं ... rappresentable संख्याओं की सीमा छोटी है; मंथिसा "काटने" को "परिशुद्धता" कम कर देता है, और एक्सपोनेंट भी सीमा को सीमित करता है: 5 हस्ताक्षरित बिट्स -6/+ 63 के खिलाफ -16 से +15 देते हैं (यदि मैंने यह सही किया ...: डी देर हो चुकी है) – ShinTakezou

+0

@ShinTakezou: निश्चित रूप से 16-बिट डेटा खोना संभव नहीं है और सटीकता खोना नहीं है ?? Float16 बहुत कम सटीक है और इस प्रकार स्वचालित रूप से कम परिशुद्धता है ... या मैं आपको गलत समझ रहा हूँ? – Goz

उत्तर

4

एक्स्पोनेंट्स अपने float32 में और float16 अभ्यावेदन शायद पक्षपातपूर्ण, और पक्षपातपूर्ण अलग ढंग से कर रहे हैं। वास्तविक एक्सपोनेंट प्राप्त करने के लिए आपको फ्लोट 32 प्रस्तुति से प्राप्त एक्सपोनेंट को अनबिज करने की आवश्यकता है, और उसके बाद फ्लोट 16 प्रतिनिधित्व के लिए इसे पूर्वाग्रहित करना होगा।

इस विस्तार के अलावा, मुझे लगता है कि यह उतना आसान है, लेकिन मैं समय-समय पर फ्लोटिंग-पॉइंट प्रस्तुतियों से आश्चर्यचकित हूं।

संपादित करें:

  1. अतिप्रवाह के लिए चेक जब घातांक के साथ बात कर रहे हैं, जबकि आप इस पर हों।

  2. आपका एल्गोरिदम मंथिसा के आखिरी बिट्स को अचानक अचानक छीनता है, जो स्वीकार्य हो सकता है लेकिन आप त्यागने वाले बिट्स को देखकर, निकटतम से कह सकते हैं। "0 ..." -> गोल नीचे, "100..001 ..." -> राउंड अप, "100..00" -> यहां तक ​​कि गोल भी।

+0

आईईईई 754 मानक में 32 बिट फ्लोटिंग पॉइंट नंबरों में मंटिसा के 23 बिट और 8 बिट्स एक्सपोनेंट हैं। – bbudge

+0

@bbudge ... काफी मेला मैं इसे स्मृति से करने की कोशिश कर रहा था। मैंने गलत गलती की, जाहिर है;) – Goz

4

प्रतिपादक, निष्पक्ष clamped और rebiased की जरूरत है। यह तेजी से कोड मैं का उपयोग करें:

unsigned int fltInt32; 
unsigned short fltInt16; 

fltInt16 = (fltInt32 >> 31) << 5; 
unsigned short tmp = (fltInt32 >> 23) & 0xff; 
tmp = (tmp - 0x70) & ((unsigned int)((int)(0x70 - tmp) >> 4) >> 27); 
fltInt16 = (fltInt16 | tmp) << 10; 
fltInt16 |= (fltInt32 >> 13) & 0x3ff; 

इस कोड को भी तेजी से प्रतिपादक के लिए एक लुकअप तालिका के साथ हो जाएगा, लेकिन मैं क्योंकि यह आसानी से एक SIMD कार्यप्रवाह करने के लिए अनुकूलित किया गया है यह एक का उपयोग करें।कार्यान्वयन की

सीमाएं:

  • बह निकला मानों float16 में नहीं दर्शाया जा सकता अपरिभाषित मूल्यों दे देंगे।
  • अंडरफ्लोइंग मान शून्य के बजाय 2^-15 और 2^-14 के बीच एक अपरिभाषित मान वापस कर देगा।
  • डेनॉर्मल्स अपरिभाषित मान देंगे।

denormals से सावधान रहें। यदि आपका आर्किटेक्चर उनका उपयोग करता है, तो वे आपके प्रोग्राम को बहुत धीमा कर सकते हैं।

संबंधित मुद्दे