2011-01-01 17 views
11

में है या नहीं, मुझे आईसीयू लाइब्रेरी (यूनिकोड के लिए अंतर्राष्ट्रीय घटक) की "source\common\unicode\utf.h" फ़ाइल में एक दिलचस्प बिट ट्विडलिंग मिला। बिट ट्विडलिंग का उद्देश्य यह जांचने के लिए किया गया था कि कोई संख्या किसी विशेष सीमा में है या नहीं।यह जांचने के लिए बिट करें कि कोई संख्या

// Is a code point in a range of U+d800..U+dbff? 
#define U_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) 

मैं जादुई संख्या (0xfffffc00) पता लगा है से आते हैं:

MagicNumber = 0xffffffff - (HighBound - LowBound) 

हालांकि, मैं यह भी पाया कि फार्मूला हर मनमाने ढंग से सीमा पर लागू नहीं होता। क्या यहां कोई व्यक्ति जानता है कि सूत्र किस परिस्थिति में काम करता है?

क्या यह जांचने के लिए एक और बिट twiddling है कि कोई संख्या विशेष सीमा में है या नहीं?

उत्तर

12

इन चालों को लागू करने के लिए, संख्याओं में उनके द्विआधारी प्रतिनिधित्व में कुछ सामान्य विशेषताएं होनी चाहिए।

0xD800 == 0b1101_1000_0000_0000 
0xDBFF == 0b1101_1011_1111_1111 

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

onlyHighBits = x & ~0x03FF 

लिखा है इस आपरेशन ("और नहीं") के बाद onlyHighBits के निचले दस बिट्स शून्य होने की गारंटी है। इसका मतलब है कि यदि यह संख्या अब अंतराल की निचली सीमा के बराबर है, तो यह पहले अंतराल में कहीं भी रही है।

यह चाल उन सभी मामलों में काम करती है जहां अंतराल की निचली और उच्च सीमा द्विआधारी में समान अंकों से शुरू होती है, और किसी बिंदु पर निचली सीमा में केवल शून्य होती है जबकि उच्च सीमा केवल एक होती है। आपके उदाहरण में यह दाईं ओर से दसवीं स्थिति पर है।

+0

क्या आप "आमतौर पर लिखे गए" के लिए कोई संदर्भ प्रदान कर सकते हैं?व्यक्तिगत रूप से मुझे 'ए & ~ बी' की बजाय कम अंतर्ज्ञानी और 'ए और बी == सी' की बजाय 'ए & ~ बी' मिलती है, 'ए और ~ डी == ई' की तुलना में अधिक अंतर्ज्ञानी होती है क्योंकि यहां कम संचालन होते हैं, भले ही यह केवल मेरी व्यक्तिगत वरीयता। –

+3

ध्यान रखें कि 'ए और बी == सी' का मतलब यह नहीं है कि आपको शायद इसका क्या अर्थ है (इसका मतलब है 'ए और (बी == सी) ')। 'ए & ~ बी' 'ए और ~ बी' के समान रूप से समान है, और मैं मानता हूं कि उत्तरार्द्ध इसका बेहतर प्रतिलेखन है, अगर केवल इसलिए कि यह आमतौर पर किया जाता है। –

3

फॉर्मूला तब भी काम करता है जब आप जिस श्रेणी को खोज रहे हैं वह 2 की शक्ति के एकाधिक से शुरू होता है (यानी 0 में संख्या समाप्त होने के बाइनरी रूप के कम अंत में 1 या अधिक बिट्स) और आकार का आकार रेंज 2^एन -1 (यानी, कम & उच्च == कम और निम्न | उच्च == उच्च) है।

+0

क्या आपने इसका परीक्षण किया है? मान लीजिए कि संख्या '9' है और सीमा' 8..8 + (2^14-1) 'है, सूत्र इस मामले पर लागू नहीं होता है। – Astaroth

+0

खैर ... एन को आधार संख्या के अंत में 0 की संख्या से बड़ा नहीं होना चाहिए (इसलिए 8 के लिए, एन 1-3 में हो सकता है)। मैंने सोचा था कि उल्लेख करने के लिए बहुत स्पष्ट होना था। – Vatine

4

2^आप एक्स सीमाओं प्रकार निम्न चाल का उपयोग कर सकते नहीं है, तो:

अगर x >= 0 और x < N आप दोनों के द्वारा जांच कर सकते हैं: तथ्य के कारण

if Longword(x) < Longword(N) then ... 

यह काम करता है कि नकारात्मक संख्या हस्ताक्षरित संख्या में हस्ताक्षरित डेटाटाइप में सबसे बड़ी संख्या के अनुरूप है।

आप का विस्तार कर सकता है यह करने के लिए है (जब सीमा जाँच अक्षम है):

if Longword(x - A) < Longword ((B - A)) then ... 

अब तुम दोनों परीक्षणों (रेंज [ A, B >) एक उप और एक सीएमपी प्लस एक भी जेसीसी में, यह मानते हुए है (बी - ए) पूर्व निर्धारित है।

मैं केवल वास्तव में आवश्यक होने पर इन प्रकार के अनुकूलन का उपयोग करता हूं; उदाहरण के लिए वे आपके कोड को कम पठनीय बनाते हैं और यह केवल प्रति परीक्षण चक्रों को बंद करता है।

भाषा पाठकों की तरह सी को नोट करें: लॉन्गवर्ड डेल्फी के हस्ताक्षर किए गए 32 बिट डेटाटाइप है।

+0

धन्यवाद @Ritsaert, मुझसे +1। – Astaroth

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