2009-03-01 20 views
6

कहें कि मेरे पास [0, 1] की सीमा में एक फ्लोट है और मैं इसे एक हस्ताक्षरित बाइट में मात्राबद्ध और स्टोर करना चाहता हूं। एक नहीं brainer की तरह लगता है, लेकिन वास्तव में यह काफी जटिल है:इंटीजर रेंज में फ़्लोट रेंज को कनवर्ट/क्वांटिज़ करें

स्पष्ट समाधान इस तरह दिखता है:

unsigned char QuantizeFloat(float a) 
{ 
    return (unsigned char)(a * 255.0f); 
} 

यह अब तक कि मैं 0 से 255 तक सभी नंबरों को मिल में काम करता है, लेकिन वितरण पूर्णांक का भी नहीं है। फ़ंक्शन केवल देता है यदि कोई 1.0f है। अच्छा समाधान नहीं है।

अगर मैं उचित राउंडिंग करना मैं सिर्फ समस्या बदलाव:

unsigned char QuantizeFloat(float a) 
{ 
    return (unsigned char)(a * 255.0f + 0.5f); 
} 

यहाँ परिणाम 0 केवल किसी अन्य संख्या की तुलना में नाव दूरी के आधे को शामिल किया गया।

मैं फ़्लोटिंग पॉइंट रेंज के बराबर वितरण के साथ क्वांटिज़ेशन कैसे करूं? आदर्श रूप से मैं पूर्णांक वितरित यादृच्छिक फ्लोट को मापने पर पूर्णांक का बराबर वितरण प्राप्त करना चाहता हूं।

कोई विचार?


बीटीडब्ल्यू: मेरा कोड सी में भी समस्या है भाषा-अज्ञेयवादी। गैर-सी लोगों के लिए: बस मान लें कि float से int रूपांतरण फ़्लोट को कम करता है।

संपादित करें: जब से हम कुछ भ्रम की स्थिति यहाँ था: मैं एक मानचित्रण कि (0) सबसे छोटी अहस्ताक्षरित चार छोटी इनपुट नाव नक्शे, और मेरे रेंज (1.0f) के उच्चतम नाव उच्चतम अहस्ताक्षरित बाइट की जरूरत है (255)।

उत्तर

10

कैसे a * 256f 256 से 255 को कम करने के लिए चेक के साथ? तो कुछ इस तरह:

return (unsigned char) (min(255, (int) (a * 256f))); 

(अपने मंच पर एक उपयुक्त मिनट समारोह के लिए - मैं इसके लिए सी समारोह याद नहीं कर सकते।)

असल में आप 256 बराबर भागों, में सीमा विभाजित करना चाहते हैं जो वह क्या करना चाहिए। 1.0 के लिए एज केस 256 पर जा रहा है और गोल करने की आवश्यकता है क्योंकि डोमेन दोनों सिरों पर समावेशी है।

+0

वाह - हाँ, बस हो गया! –

+0

हां - (हस्ताक्षरित चार) (ए * 256.0 एफ) आपको 1.0 के अलावा प्रत्येक इनपुट मान के लिए बिल्कुल वही देता है जो आप चाहते हैं।सी में कोई अंतर्निहित न्यूनतम कार्य नहीं है, इसलिए यदि आप पहले से नहीं हैं तो आपको अपना खुद का लिखना होगा। –

+0

जॉन, मैं एक ही परिणाम के साथ आया, बस एक्सेल स्प्रेडशीट से इसे सही तरीके से स्थानांतरित करने में सक्षम नहीं था। मैंने अपना शर्मनाक जवाब हटा दिया। – cdonner

1

मुझे लगता है कि आप देख रहे हैं यह है:

unsigned char QuantizeFloat (float a) 
{ 
    return (unsigned char) (a * 256.0f); 
} 

यह [0, 255] में एक समान बाइट मूल्यों के लिए वर्दी नाव मान मैप जाएगा [1 0,]। [I/256, (i + 1)/256 [(जो कि (i + 1)/256 को छोड़कर है) में सभी मान, 0..255 में, मैं मैप किए गए हैं। अवांछित क्या हो सकता है कि 1.0f को 256.0f पर मैप किया गया है जो 0

0

एक समान वितरण को बनाए रखने के दौरान एक-एक त्रुटि को फैल सकता है, जबकि आप 31 दिसंबर के अंत में एक छलांग लगाएंगे ।

limit = 4 
maxi = limit - 1 

n = 16 
for i in range(n): 
    x = i/(n - 1) 

    a = x * maxi # Wrong distribution 
    b = x * limit # One off 
    c = x * (limit - 1/limit) 

    print(f"{x:.3f} | {a:.3f} | {b:.3f} | {c:.3f}") 

-

0.000 | 0.000 | 0.000 | 0.000 
0.067 | 0.200 | 0.267 | 0.250 
0.133 | 0.400 | 0.533 | 0.500 
0.200 | 0.600 | 0.800 | 0.750 
0.267 | 0.800 | 1.067 | 1.000 
0.333 | 1.000 | 1.333 | 1.250 
0.400 | 1.200 | 1.600 | 1.500 
0.467 | 1.400 | 1.867 | 1.750 
0.533 | 1.600 | 2.133 | 2.000 
0.600 | 1.800 | 2.400 | 2.250 
0.667 | 2.000 | 2.667 | 2.500 
0.733 | 2.200 | 2.933 | 2.750 
0.800 | 2.400 | 3.200 | 3.000 
0.867 | 2.600 | 3.467 | 3.250 
0.933 | 2.800 | 3.733 | 3.500 
1.000 | 3.000 | 4.000 | 3.750 
संबंधित मुद्दे