2010-12-11 10 views
6

के लिए त्वरित पूर्णांक लॉगरिदम मेरे पास 32-8191 से पूर्णांक मान हैं जो मैं लगभग लॉगरिदमिक पैमाने पर मैप करना चाहता हूं। अगर मैं आधार 2 का उपयोग कर रहा था, तो मैं केवल प्रमुख शून्य बिट्स को गिन सकता था और उन्हें 8 स्लॉट में मैप कर सकता था, लेकिन यह भी बहुत कोर्स किया गया है; मुझे 32 स्लॉट चाहिए (और अधिक बेहतर होगा, लेकिन मुझे 32-बिट मान में बिट्स पर मैप करने की आवश्यकता है), जो लॉगरिदम के लिए लगभग 1.18-1.20 के आधार पर आता है। इस मूल्य की गणना करने के लिए किसी के पास कुछ चाल हैं, या उचित अनुमान, बहुत तेज़?विशेष मामले

मेरा अंतर्ज्ञान रेंज को सशर्त के साथ 2 या 3 सब्रैंज में तोड़ना है, और प्रत्येक के लिए एक छोटी लुकअप टेबल का उपयोग करना है, लेकिन मुझे आश्चर्य है कि क्या कुछ चाल है जो मैं गिनती-अग्रणी-शून्य के साथ कर सकता हूं, फिर परिणाम को परिष्कृत कर सकता हूं, खासतौर से जब परिणाम सटीक नहीं होते हैं लेकिन केवल मोटे तौर पर लॉगरिदमिक होते हैं।

उत्तर

4

क्यों अग्रणी बिट के अलावा अगले दो बिट्स का उपयोग न करें। आप पहले संख्या को 8 बिन में विभाजित कर सकते हैं, और अगले दो बिट्स को प्रत्येक बिन को चार में विभाजित करने के लिए कर सकते हैं। इस मामले में, आप एक साधारण शिफ्ट ऑपरेशन का उपयोग कर सकते हैं जो बहुत तेज़ है।

संपादित करें: यदि आपको लगता है कि लॉगरिदम का उपयोग करना एक व्यवहार्य समाधान है। यहां सामान्य एल्गोरिदम है:

a लॉगरिदम का आधार बनें, और सीमा (b_min, b_max) = (32,8191) है। आप सूत्र का उपयोग कर आधार पा सकते हैं:

log(b_max/b_min)/log(a) = 32 bin 

जो आप a~1.1892026 दे। यदि आप इसे लॉगरिदम के आधार के रूप में उपयोग करते हैं, तो आप (b_min, b_max)(log_a(b_min), log_a(b_max)) = (20.0004,52.0004) में श्रेणी को मानचित्र कर सकते हैं।

अब (0,32) श्रेणी प्राप्त करने के लिए आपको केवल 20.0004 द्वारा सभी तत्वों को घटाना होगा। यह गारंटी देता है कि सभी तत्व लॉगरिदमिक वर्दी हैं। हो गया

नोट: या तो संख्यात्मक त्रुटि के कारण कोई तत्व सीमा से बाहर हो सकता है। आपको सटीक मूल्य के लिए स्वयं की गणना करनी चाहिए।

टिप्पणी 2: log_a (ख) = लॉग (ख)/लॉग (क)

+0

मैं कुछ है कि (dlmalloc मन में आता है) से पहले किया देखा है, लेकिन मैं अगर मैं की तरह यह कितनी दूर लघुगणक से भटक नहीं जानते ।शायद यह बुरा नहीं है हालांकि। –

+0

मुझे आश्चर्य है कि क्या मैं उन बिट्स को मेरे लिए अच्छी तरह से इकट्ठा करने के लिए फ़्लोटिंग पॉइंट का उपयोग कर सकता हूं ... –

2

टेबल देखने, एक विकल्प है कि तालिका कि बड़ा नहीं है। यदि एक 8 के तालिका बहुत बड़ी है, और आपके पास अग्रणी शून्य निर्देश है, तो आप शीर्ष कुछ बिट्स पर एक टेबल लुकअप का उपयोग कर सकते हैं।

nbits = 32 - count_leading_zeros(v) # number of bits in number 
highbits = v >> (nbits - 4)   # top 4 bits. Top bit is always a 1. 
log_base_2 = nbits + table[highbits & 0x7] 

तालिका आप log_2

table[i] = approx(log_2(1 + i/8.0)) 

आप, पूर्णांक गणित में रहने के लिए एक सुविधाजनक पहलू से अंतिम पंक्ति गुणा करने के लिए चाहते हैं के कुछ सन्निकटन के साथ पॉप्युलेट।

+0

8k तालिका बहुत बड़ी है, लेकिन 8-32 प्रविष्टियों वाला एक टेबल खराब नहीं होगा। मुझे हालांकि hwlau के समाधान की सादगी पसंद है। –

+0

मुझे लगता है कि हमारे समाधान प्रभावी रूप से समान हैं (मेरा अगला 3 बिट्स का उपयोग करता है, लेकिन यह कॉन्फ़िगर करने योग्य है)। –

2

उत्तर मैं सिर्फ आईईईई 754 में आधारित चल बिन्दु के साथ आया था:

((union { float v; uint32_t r; }){ x }.r >> 21 & 127) - 16 

यह (hwlau के जवाब के रूप में ही) 32-8192 0-31 पर मोटे तौर पर लघुगणकीय मैप करता है।

उन्नत संस्करण (बेकार बिटवाइज़ और काट):

((union { float v; uint32_t r; }){ x }.r >> 21) - 528 
+0

आप बिन की अन्य संख्या में कैसे पुन: सहेजते हैं? – unsym

+0

पुनर्विक्रय .......? –

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