^ = 32 के पीछे क्या विचार है, जो निचले अक्षरों को ऊपरी और इसके विपरीत में परिवर्तित करता है?


146

मैं codeforces पर कुछ समस्या को हल कर रहा था। आम तौर पर मैं पहले जांचता हूं कि अगर चरित्र ऊपरी या निचला अंग्रेजी अक्षर है तो 32इसे संबंधित पत्र में परिवर्तित करने के लिए घटाएं या जोड़ें । लेकिन मैंने पाया कि कोई ऐसा ^= 32ही काम करता है। यह रहा:

char foo = 'a';
foo ^= 32;
char bar = 'A';
bar ^= 32;
cout << foo << ' ' << bar << '\n'; // foo is A, and bar is a

मैंने इसके लिए स्पष्टीकरण खोजा है और इसका पता नहीं लगाया है। तो यह काम क्यों करता है?


5
en.wikipedia.org/wiki/File:USASCII_code_chart.png टिप: आप @का उपयोग करके 'में परिवर्तित कर सकते हैं ^ 32
KamilCuk

112
FWIW, यह वास्तव में "काम" नहीं करता है। यह इस विशेष वर्ण सेट के लिए काम करता है, लेकिन ऐसे अन्य सेट हैं जहां यह आपको उपयोग नहीं करना चाहिए toupperऔर tolowerमामलों को स्विच करना चाहिए ।
नेथनऑलिवर

7
ऑनलाइन प्रतियोगिता "विचार" के साथ कुछ समय इस तरह से एक मोटे तरीके से कोड लिखने के लिए है कि यह एक गंभीर समीक्षा कभी नहीं होगा;)
idclev 463035818

21
^ = XOR का उपयोग करके मूल्य बदल रहा है। अपरकेस ASCII अक्षरों में संबंधित बिट में शून्य होता है, जबकि लोअरकेस अक्षरों में एक होता है। उस ने कहा, कृपया नहीं! लोअरकेस और अपरकेस के बीच कनवर्ट करने के लिए उचित चरित्र (यूनिकोड) दिनचर्या का उपयोग करें। सिर्फ ASCII का युग लंबा चला है।
हंस-मार्टिन मोजर

14
ऐसा नहीं है कि यह केवल कुछ चरित्र सेट के साथ काम करता है। भले ही हम यह मान लें कि सारी दुनिया UTF-8 है (जो कम से कम एक अच्छा यूटोपियन लक्ष्य हो सकता है), यह भी केवल 26 अक्षरों के साथ काम करता Aहै Z। यह तब तक ठीक है जब तक आप केवल अंग्रेजी के बारे में परवाह करते हैं (और "भोलेपन", "कैफ़े", या डियाट्रिटिक्स के नाम जैसे शब्दों का उपयोग नहीं करते हैं), लेकिन दुनिया सिर्फ अंग्रेजी नहीं है।
इलकाचू

जवाबों:


149

आइए बाइनरी में एएससीआईआई कोड तालिका पर एक नज़र डालें।

A 1000001    a 1100001
B 1000010    b 1100010
C 1000011    c 1100011
...
Z 1011010    z 1111010

और 32 0100000जो लोअरकेस और अपरकेस अक्षरों के बीच एकमात्र अंतर है। तो उस बिट को टॉगल करना एक पत्र के मामले को जन्म देता है।


49
"केस टॉगल करता है" * केवल ASCII के लिए
Mooing Duck

39
@ ASCII में केवल ए-ज़-ज़ के लिए पूजन करना। लोअर के मामले "[" है नहीं "{"।
dbkk

21
@dbkk {से छोटा है [, इसलिए यह "कम" मामला है। नहीं? ठीक है, मैं खुद को दिखाऊंगा: डी
पीटर बैडिआ

25
सामान्य ज्ञान tidbit: 7 बिट क्षेत्र में, जर्मन कंप्यूटरों ने [] {|} को toäöü में भेजा क्योंकि हमें उन पात्रों की तुलना में उमलाट्स की आवश्यकता थी, इसलिए उस संदर्भ में, {(ä) वास्तव में लोअरकेस था [(Ä)]।
गुंटराम ब्लोम

14
@GuntramBlohm आगे चलकर ट्रिविया टिडबिट, यही कारण है कि IRC सर्वर विचार करते हैं foobar[] और foobar{}समान उपनाम होते हैं, क्योंकि उपनाम मामले असंवेदनशील होते हैं , और IRC स्कैंडिनेविया में इसकी उत्पत्ति है :)
ZXKnight

117

यह इस तथ्य का उपयोग करता है कि ASCII मूल्यों को वास्तव में स्मार्ट लोगों द्वारा चुना गया है।

foo ^= 32;

यह 6 सबसे कम बिट flips 1 के foo(के ASCII तरह अपरकेस झंडा), एक छोटे अक्षर और करने के लिए एक ASCII अपर केस बदलने उपाध्यक्ष प्रतिकूल

+---+------------+------------+
|   | Upper case | Lower case |  32 is 00100000
+---+------------+------------+
| A | 01000001   | 01100001   |
| B | 01000010   | 01100010   |
|            ...              |
| Z | 01011010   | 01111010   |
+---+------------+------------+

उदाहरण

'A' ^ 32

    01000001 'A'
XOR 00100000 32
------------
    01100001 'a'

और XOR की संपत्ति से, 'a' ^ 32 == 'A'

नोटिस

वर्णों का प्रतिनिधित्व करने के लिए ASCII का उपयोग करने के लिए C ++ की आवश्यकता नहीं है। एक अन्य संस्करण EBCDIC है । यह ट्रिक केवल ASCII प्लेटफॉर्म पर काम करती है। एक और पोर्टेबल समाधान का उपयोग करना होगा std::tolowerऔर std::toupper, पेशकश बोनस के साथ स्थानीय-जागरूक होने के लिए (यह स्वचालित रूप से आपकी सभी समस्याओं को हल नहीं करता है, हालांकि टिप्पणियां देखें):

bool case_incensitive_equal(char lhs, char rhs)
{
    return std::tolower(lhs, std::locale{}) == std::tolower(rhs, std::locale{}); // std::locale{} optional, enable locale-awarness
}

assert(case_incensitive_equal('A', 'a'));

1) जैसा कि 32 है 1 << 5(2 से 5 शक्ति), यह 6 बिट (1 से गिनती) में फ़्लिप करता है।


16
EBCDIC को कुछ बहुत ही स्मार्ट लोगों द्वारा भी चुना गया था: छिद्रित कार्ड पर वास्तव में अच्छी तरह से काम करता है cf। ASCII जो एक गड़बड़ है। लेकिन यह एक अच्छा जवाब है, +1।
स्नानागार

65
मुझे पंच कार्ड के बारे में नहीं पता है, लेकिन ASCII का उपयोग कागज टेप पर किया गया था । यही कारण है कि हटाए गए वर्ण को 1111111 के रूप में एन्कोड किया गया है: इसलिए आप किसी भी वर्ण को टेप पर उसके कॉलम के सभी छेदों को छिद्र करके "हटाए गए" के रूप में चिह्नित कर सकते हैं।
dan04

23
@Bathsheba किसी ऐसे व्यक्ति के रूप में जिसने पंचकार्ड का उपयोग नहीं किया है, यह मेरे दिमाग को इस विचार के इर्द-गिर्द लपेटना बहुत मुश्किल है कि EBCDIC को बुद्धिमानी से डिजाइन किया गया था।
लॉर्ड फरक्वाड

9
@LordFarquaad IMHO एक पंचकार्ड पर अक्षर कैसे लिखे जाते हैं, इसकी विकिपीडिया तस्वीर इस बात पर स्पष्ट चित्रण करती है कि EBCDIC इस एन्कोडिंग के लिए कुछ (लेकिन कुल, देखें / बनाम) अर्थ नहीं बनाता है। en.wikipedia.org/wiki/EBCDIC#/media/…
पीटरिस

11
@ dan04 नोट "MASSE 'का निम्न-मामला रूप क्या है?" उन लोगों के लिए जो नहीं जानते हैं, जर्मन में दो शब्द हैं जिनके ऊपरी मामले का स्वरूप MASSE है; एक "मस्से" है और दूसरा "माए" है। tolowerजर्मन में उचित केवल एक शब्दकोश की जरूरत नहीं है, यह अर्थ को पार्स करने में सक्षम होने की जरूरत है।
मार्टिन बोनर

35

मुझे यह कहने की अनुमति दें कि यह है - हालांकि यह स्मार्ट लगता है - वास्तव में, वास्तव में बेवकूफ हैक। अगर कोई आपको 2019 में यह सलाह देता है, तो उसे मारो। उसे उतना ही मारो जितना आप कर सकते हैं।
आप निश्चित रूप से, इसे अपने स्वयं के सॉफ़्टवेयर में कर सकते हैं जिसे आप और कोई नहीं उपयोग करता है यदि आप जानते हैं कि आप किसी भी भाषा का उपयोग नहीं करेंगे, लेकिन वैसे भी अंग्रेजी। नहीं तो नहीं।

हैक कुछ 30-35 साल पहले विवाद-योग्य "ठीक है" था, जब कंप्यूटर वास्तव में नहीं था ASCII में ज्यादा लेकिन अंग्रेजी करते हैं, और शायद एक या दो प्रमुख यूरोपीय भाषाओं। लेकिन ... अब ऐसा नहीं है।

हैक काम करता है क्योंकि यूएस-लैटिन ऊपरी- और लोअरकेस 0x20एक दूसरे से बिल्कुल अलग हैं और एक ही क्रम में दिखाई देते हैं, जो सिर्फ एक अंतर है। जो, वास्तव में, यह बिट हैक करता है, टॉगल करता है।

अब, पश्चिमी यूरोप और बाद में यूनिकोड संघ के लिए कोड पृष्ठ बनाने वाले लोग इस योजना को रखने के लिए काफी चतुर थे, जैसे कि जर्मन उमलाट्स और फ्रांसीसी-उच्चारण स्वर। के लिए ऐसा नहीं है (जब तक कि किसी ने 2017 में यूनिकोड कंसोर्टियम को आश्वस्त नहीं किया, और एक बड़ी फेक न्यूज प्रिंट पत्रिका ने इसके बारे में लिखा, वास्तव में डुडेन को आश्वस्त करना - उस पर कोई टिप्पणी नहीं ) एक छद्म के रूप में (एसएस के रूप में परिवर्तित) । अब यह है के रूप में versal मौजूद हैं, लेकिन दो हैं 0x1DBFपदों के अलावा, नहीं 0x20

हालाँकि, कार्यान्वयनकर्ता इस बात को ध्यान में नहीं रखते थे कि यह चालू रहे। उदाहरण के लिए, यदि आप अपने हैक को कुछ पूर्वी यूरोपीय भाषाओं में या जैसे (मैं सिरिलिक के बारे में नहीं जानता हूं) लागू करते हैं, तो आपको एक बुरा आश्चर्य मिलेगा। उन सभी "हैचेट" वर्ण उस के उदाहरण हैं, लोअरकेस और अपरकेस एक अलग हैं। इस प्रकार हैक वहाँ ठीक से काम नहीं करता है ।

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

यह भी मत सोचो कि यह हैक थाई या चीनी की तरह क्या करेगा (यह सिर्फ आपको पूरी बकवास देगा)।

30 साल पहले सौ सीपीयू साइकिल की बचत करना बहुत सार्थक रहा होगा, लेकिन आजकल, एक स्ट्रिंग को ठीक से बदलने के लिए वास्तव में कोई बहाना नहीं है। इस गैर-तुच्छ कार्य को करने के लिए पुस्तकालय के कार्य हैं।
कई दर्जन किलोबाइट के पाठ को ठीक से बदलने के लिए लिया गया समय आजकल नगण्य है।


2
मैं पूरी तरह से सहमत हूँ - हालांकि यह हर प्रोग्रामर के लिए एक अच्छा विचार है कि यह क्यों काम करता है - यह भी एक अच्छा साक्षात्कार प्रश्न बना सकता है .. यह क्या करता है और इसका उपयोग कब किया जाना चाहिए :)
बिल के

33

यह काम करता है, क्योंकि जैसा कि होता है, ASCII और व्युत्पन्न एन्कोडिंग्स में 'ए' और ए 'के बीच का अंतर 32 है, और 32 भी छठे बिट का मूल्य है। एक विशेष के साथ 6 बिट को फ़्लिप करना या इस प्रकार ऊपरी और निचले के बीच कनवर्ट करता है।


22

सबसे अधिक संभावना है कि चरित्र सेट का आपका कार्यान्वयन ASCII होगा। यदि हम तालिका देखें:

यहाँ छवि विवरण दर्ज करें

हम देखते हैं कि 32एक लोअरकेस और अपरकेस संख्या के मूल्य के बीच का अंतर है । इसलिए, यदि हम करते हैं^= 32 (जो कि 6 वीं सबसे महत्वपूर्ण बिट को टॉगल करने के लिए बराबर है), यह एक लोअरकेस और अपरकेस चरित्र के बीच बदलता है।

ध्यान दें कि यह सभी प्रतीकों के साथ काम करता है, न कि केवल अक्षरों के साथ। यह संबंधित चरित्र के साथ एक चरित्र को जन्म देता है जहां 6 बिट अलग होता है, जिसके परिणामस्वरूप पात्रों की एक जोड़ी होती है जो बीच-बीच में आगे-पीछे होती है। अक्षरों के लिए, संबंधित ऊपरी / निचले अक्षर ऐसे जोड़े बनाते हैं। ए NULमें Spaceऔर दूसरे तरीके से बदल जाएगा , और @बैकटीक के साथ टॉगल होगा। मूल रूप से इस चार्ट पर पहले कॉलम में कोई भी चरित्र एक कॉलम ओवर के साथ आता है, और तीसरे और चौथे कॉलम पर भी यही लागू होता है।

मैं इस हैक का उपयोग नहीं करूंगा, क्योंकि इसकी कोई गारंटी नहीं है कि यह किसी भी सिस्टम पर काम करने वाला है। बस का उपयोग toupper और tolower बजाय, और के रूप में ऐसे प्रश्नों isupper


2
खैर, यह उन सभी अक्षरों के लिए काम नहीं करता है जिनमें 32 का अंतर है। अन्यथा, यह '@' और '' के बीच काम करेगा!
मैथ्यू ब्रूचर

2
@ मैथ्यू ब्रूचर यह काम कर रहा है, 32 ^ 320 है, 64 नहीं
नाथनऑलिवर

5
'' '' और '' '' अक्षर '' नहीं हैं। केवल [a-z]और [A-Z]"अक्षर" हैं। बाकी सभी संयोग हैं जो एक ही नियम का पालन करते हैं। अगर कोई आपसे "ऊपरी मामले]" के बारे में पूछे, तो यह क्या होगा? यह अभी भी "]" - "}" "" का "ऊपरी मामला" नहीं है।
आजादी-मी।

4
@ मैथ्यू ब्रूचर: उस बिंदु को बनाने का एक और तरीका यह है कि निचले-मामले और ऊपरी-केस अल्फाबेटिक रेंज %32ASCII कोडिंग सिस्टम में "संरेखण" सीमा को पार नहीं करते हैं । यही कारण है कि बिट 0x20एक ही अक्षर के ऊपरी / निचले मामले संस्करणों के बीच एकमात्र अंतर है। यदि यह मामला नहीं था, तो आपको जोड़ने या घटाना होगा 0x20, न कि केवल टॉगल करने के लिए, और कुछ अक्षरों के लिए अन्य उच्च बिट्स को फ्लिप करने के लिए ले-आउट करना होगा। (और एक ही ऑपरेशन टॉगल नहीं कर सकता है, और पहली जगह में वर्णमाला वर्णों की जांच करना कठिन होगा क्योंकि आप |= 0x20जाली लगाने के लिए मजबूर नहीं कर सकते हैं ।)
पीटर कॉर्ड्स

2
+1 उन सभी को याद दिलाने के लिए जो asciitable.com को उस सटीक ग्राफिक (और विस्तारित ASCII संस्करण !!) को घूरने की याद दिलाते हैं, पिछले, मैं 15 साल या 20 साल से?
एसी

15

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

स्पष्ट रूप से, यह आज के सौदे के लगभग उतना बड़ा नहीं है जितना कि 1960 में (जब एएससीआईआई पर काम शुरू हुआ था) तेज प्रोसेसर और यूनिकोड के कारण, लेकिन अभी भी कुछ कम लागत वाले प्रोसेसर हैं जो कि एक महत्वपूर्ण अंतर ला सकते हैं। जब तक आप केवल ASCII वर्णों की गारंटी दे सकते हैं।

https://en.wikipedia.org/wiki/Bitwise_operation

साधारण कम-लागत वाले प्रोसेसर पर, आम तौर पर, बिटवाइज़ ऑपरेशंस विभाजन की तुलना में बहुत अधिक तेज़ होते हैं, कई बार गुणा से तेज़ होते हैं, और कभी-कभी इसके अलावा काफी तेज़ होते हैं।

नोट: मैं कई कारणों (पठनीयता, शुद्धता, पोर्टेबिलिटी, आदि) के लिए तार के साथ काम करने के लिए मानक पुस्तकालयों का उपयोग करने की सिफारिश करूंगा। केवल बिट फ्लिपिंग का उपयोग करें यदि आपने प्रदर्शन को मापा है और यह आपकी अड़चन है।


14

यह कैसे ASCII काम करता है, यह सब है।

लेकिन इस शोषण में, आप पोर्टेबिलिटी छोड़ रहे हैं क्योंकि C ++ एन्कोडिंग के रूप में ASCII पर जोर नहीं देता है।

यही कारण है कि फ़ंक्शन std::toupperऔर std::tolowerC ++ मानक लाइब्रेरी में कार्यान्वित किए जाते हैं - आपको इसके बजाय उनका उपयोग करना चाहिए।


6
हालांकि प्रोटोकॉल हैं, जिनके लिए एएससीआईआई का उपयोग करना आवश्यक है, जैसे कि डीएनएस। वास्तव में, "0x20 चाल" का उपयोग कुछ DNS सर्वरों द्वारा DNS क्वेरी में एंटी-स्पूफिंग तंत्र के रूप में अतिरिक्त एन्ट्रापी डालने के लिए किया जाता है। DNS केस असंवेदनशील है, लेकिन यह भी मामला संरक्षित करने वाला है, इसलिए यदि यादृच्छिक मामले के साथ एक क्वेरी भेजें और उसी मामले को वापस लें यह एक अच्छा संकेत है कि प्रतिक्रिया किसी तीसरे पक्ष द्वारा खराब नहीं की गई है।
अलनीतक 14

यह उल्लेखनीय है कि बहुत सारे एनकोडिंग में अभी भी मानक (विस्तारित) ASCII वर्णों के लिए समान प्रतिनिधित्व नहीं है। लेकिन फिर भी, यदि आप वास्तव में विभिन्न एन्कोडिंग के बारे में चिंतित हैं तो आपको उचित कार्यों का उपयोग करना चाहिए।
कप्तान मैन

5
@CaptainMan: बिल्कुल। UTF-8 सरासर सुंदरता की चीज है। उम्मीद है कि यह C ++ मानक इंसोफर में "अवशोषित" हो जाता है जो IEEE754 में फ्लोटिंग पॉइंट के लिए है।
बाथशीबा

11

दूसरी तालिका देखें http://www.catb.org/esr/faqs/things-every-hacker-once-knew/#_ascii , और निम्नलिखित नोट, नीचे पुन: प्रस्तुत:

आपके कीबोर्ड पर नियंत्रण संशोधक मूल रूप से आपके द्वारा टाइप किए जाने वाले किसी भी वर्ण के शीर्ष तीन बिट्स को साफ़ करता है, नीचे के पाँच को छोड़ कर 0..31 रेंज पर मैप करता है। इसलिए, उदाहरण के लिए, Ctrl-SPACE, Ctrl- @, और Ctrl-`सभी का एक ही मतलब है: NUL।

बहुत पुराने कीबोर्ड केवल कुंजी के आधार पर 32 या 16 बिट को टॉगल करके शिफ्ट करते थे; यही कारण है कि ASCII में छोटे और बड़े अक्षरों के बीच का संबंध इतना नियमित है, और संख्याओं और प्रतीकों के बीच और कुछ जोड़े प्रतीकों के बीच का संबंध नियमित है, अगर आप इस पर ध्यान केंद्रित करते हैं। ASR-33, जो एक ऑल-अपरकेस टर्मिनल था, यहां तक ​​कि आप कुछ विराम वर्ण उत्पन्न करते हैं, जिसमें 16 बिट को शिफ्ट करने की कुंजी नहीं थी; इस प्रकार, उदाहरण के लिए, Shift-K (0x4B) एक बन गया [(0x5B)

ASCII को इस तरह डिजाइन किया गया था कि shiftऔर ctrlकीबोर्ड कीज़ को बिना ctrlतर्क के (या शायद किसी भी ) तर्क के बिना लागू किया जा सकता है - shiftशायद केवल कुछ फाटकों की आवश्यकता होती है। यह संभवतः वायर प्रोटोकॉल को स्टोर करने के लिए किसी भी अन्य वर्ण एन्कोडिंग (कोई सॉफ़्टवेयर रूपांतरण की आवश्यकता नहीं) के रूप में कम से कम समझ में आता है।

जुड़ा हुआ लेख कई अजीब हैकर सम्मेलनों को भी समझाता है जैसे And control H does a single character and is an old^H^H^H^H^H classic joke.( यहां पाया गया )।


1
ASCII w / के अधिक के लिए एक बदलाव टॉगल लागू कर सकता है foo ^= (foo & 0x60) == 0x20 ? 0x10 : 0x20, हालांकि यह केवल ASCII है और इसलिए अन्य उत्तरों में वर्णित कारणों के लिए नासमझ है। यह शायद w / शाखा-मुक्त प्रोग्रामिंग में भी सुधार किया जा सकता है।
इरिदिन

1
आह, foo ^= 0x20 >> !(foo & 0x40)सरल होगा। यह भी एक अच्छा उदाहरण है कि क्यों terse कोड को अक्सर अपठनीय ^ _ ^ माना जाता है।
इरिदिन

8

32 (00100000 बाइनरी में) के साथ एक्सरिंग छठी बिट (दाईं ओर से) सेट या रीसेट करता है। यह 32 को जोड़ने या घटाने के लिए सख्ती से बराबर है।


2
यह कहने का एक और तरीका यह है कि XOR बिना-कैरी का है।
पीटर कॉर्ड्स

7

निचले-मामले और ऊपरी-केस अल्फाबेटिक रेंज %32ASCII कोडिंग सिस्टम में "संरेखण" सीमा को पार नहीं करते हैं ।

यही कारण है कि बिट 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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.