निचले-मामले और ऊपरी-केस अल्फाबेटिक रेंज %32
ASCII कोडिंग सिस्टम में "संरेखण" सीमा को पार नहीं करते हैं ।
यही कारण है कि बिट 0x20
एक ही अक्षर के ऊपरी / निचले मामले संस्करणों के बीच एकमात्र अंतर है।
यदि यह मामला नहीं था, तो आपको जोड़ने या घटाना होगा 0x20
, न कि केवल टॉगल करने के लिए, और कुछ अक्षरों के लिए अन्य उच्च बिट्स को फ्लिप करने के लिए कैरी-आउट होगा। (और एक भी ऑपरेशन नहीं होगा जो टॉगल कर सकता है, और पहली जगह में वर्णमाला वर्णों की जांच कर रहा है क्योंकि आप नहीं कर सकते हैं क्योंकि = = 0x20 को बल देने के लिए।)
संबंधित एएससीआईआई-केवल ट्रिक्स: आप एक अल्फाबेटिक एएससीआईआई चरित्र के लिए लोअरकेस को मजबूर कर सकते हैं c |= 0x20
और फिर (यदि अहस्ताक्षरित) जांच कर रहे हैं c - 'a' <= ('z'-'a')
। तो सिर्फ 3 ऑपरेशन: या + SUB + CMP लगातार 25 के खिलाफ। बेशक, कंपाइलर जानते हैं कि (c>='a' && c<='z')
आपके लिए इस तरह से कैसे ऑप्टिमाइज़ करना है , इसलिए अधिकांश c|=0x20
भाग आपको खुद करना चाहिए । अपने आप को सभी आवश्यक कास्टिंग करने के लिए असुविधाजनक है, विशेष रूप से हस्ताक्षरित करने के लिए डिफ़ॉल्ट पूर्णांक पदोन्नति के आसपास काम करना int
।
unsigned char lcase = y|0x20;
if (lcase - 'a' <= (unsigned)('z'-'a')) { // lcase-'a' will wrap for characters below 'a'
// c is alphabetic ASCII
}
// else it's not
यह भी देखें कि C ++ टू अपर केस ( toupper
केवल ASCII के लिए SIMD स्ट्रिंग) में स्ट्रिंग को कन्वर्ट करें , उस चेक का उपयोग करके XOR के लिए ऑपरेटर को मास्किंग करें।)
और यह भी कि कैसे एक चर सरणी का उपयोग करें और निचले मामले के अक्षरों को ऊपरी मामले में बदल दें, और इसके विपरीत
(सीएमडी इंट्रिंसिक्स के साथ सी, और स्केलर x86 एएसएम केस-फ्लिप अल्फ़ाबेटिक ASCII वर्णों के लिए, दूसरों को बिना बताए छोड़ दें।)
ये ट्रिक्स ज्यादातर तभी उपयोगी होती हैं, जब SIMD (जैसे SSE2 या NEON) के साथ कुछ टेक्स्ट-प्रोसेसिंग को हाथ से ऑप्टिमाइज़ किया जाए, यह जाँचने के बाद कि char
सदिश में कोई भी अपने उच्च बिट सेट के साथ नहीं है। (और इस प्रकार कोई भी बाइट एक एकल वर्ण के लिए एक बहु-बाइट UTF-8 एन्कोडिंग का हिस्सा नहीं है, जिसमें अलग-अलग ऊपरी / निचले-मामले उलट हो सकते हैं)। यदि आपको कोई मिलता है, तो आप 16 बाइट्स के इस भाग के लिए, या बाकी स्ट्रिंग के लिए स्केलर पर वापस आ सकते हैं।
यहाँ तक कि कुछ ऐसे स्थान भी हैं जहाँ toupper()
या tolower()
ASCII श्रेणी के कुछ वर्ण उस श्रेणी के बाहर के वर्ण उत्पन्न करते हैं, विशेष रूप से तुर्की जहाँ मैं İ ı और ↔ ↔ i। उन स्थानों में, आपको एक अधिक परिष्कृत जांच की आवश्यकता होगी, या शायद इस अनुकूलन का उपयोग करने की कोशिश न करें।
लेकिन कुछ मामलों में, आपको UTF-8 के बजाय ASCII मानने की अनुमति है, उदाहरण के लिए LANG=C
(POSIX लोकेल), en_CA.UTF-8
या जो भी हो , के साथ यूनिक्स उपयोगिताओं ।
लेकिन अगर आप इसे सुरक्षित कर सकते हैं, तो आप एक लूप (जैसे 5x) में toupper
कॉल करने की तुलना में बहुत तेज़ी से मध्यम-लंबाई के तार लगा सकते हैं toupper()
, और अंतिम बार मैंने बूस्ट 1.58 के साथ परीक्षण किया , जो बहुत तेज़ी से हर चरित्र के लिए boost::to_upper_copy<char*, std::string>()
एक बेवकूफ बनाता है dynamic_cast
।
@
का उपयोग करके 'में परिवर्तित कर सकते हैं^ 32
।