ตัวอักษรตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ช่วงไม่ข้าม%32
ขอบเขต "การจัดตำแหน่ง" ในระบบการเข้ารหัส ASCII
นี่คือเหตุผลที่ bit 0x20
เป็นความแตกต่างเพียงอย่างเดียวระหว่างตัวอักษรตัวใหญ่ / ตัวเล็กในรุ่นเดียวกัน
หากไม่ใช่ในกรณีนี้คุณจะต้องเพิ่มหรือลบ0x20
ไม่ใช่แค่สลับและสำหรับตัวอักษรบางตัวจะมีการดำเนินการเพื่อพลิกบิตที่สูงขึ้นอื่น ๆ (และจะไม่มีการดำเนินการเดียวที่สามารถสลับได้และการตรวจสอบตัวอักษรในสถานที่แรกจะยากกว่าเพราะคุณไม่สามารถ | = 0x20 เพื่อบังคับให้ lcase)
ที่เกี่ยวข้องกับเทคนิค ASCII เท่านั้น: คุณสามารถตรวจสอบสำหรับอักขระ ASCII ตัวอักษรด้วยการบังคับให้เป็นตัวพิมพ์เล็กด้วยc |= 0x20
แล้วตรวจสอบว่า c - 'a' <= ('z'-'a')
(ไม่ได้ลงนาม) ดังนั้นแค่ 3 การทำงาน: + + SUB + CMP เทียบกับค่าคงที่ 25 แน่นอนว่าคอมไพเลอร์รู้วิธีเพิ่มประสิทธิภาพให้กับ(c>='a' && c<='z')
asm เช่นนี้สำหรับคุณดังนั้นส่วนใหญ่คุณควรทำ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 ++ เป็นตัวพิมพ์ใหญ่ (สตริง SIMD toupper
สำหรับ ASCII เท่านั้น, ปิดบังตัวถูกดำเนินการสำหรับ XOR โดยใช้การตรวจสอบนั้น)
และวิธีเข้าถึงอาร์เรย์ char และเปลี่ยนตัวอักษรตัวพิมพ์เล็กเป็นตัวพิมพ์ใหญ่และในทางกลับกัน
(C ที่มี SIMD ภายในและ scalar x86 asm case-flip สำหรับอักขระ ASCII ตัวอักษรทำให้ผู้อื่นไม่ได้รับการแก้ไข)
เทคนิคเหล่านี้ส่วนใหญ่จะมีประโยชน์ก็ต่อเมื่อการเพิ่มประสิทธิภาพการประมวลผลข้อความด้วยมือ (เช่น SSE2 หรือ NEON) ด้วยมือเมื่อตรวจสอบว่าไม่มีchar
s ในเวกเตอร์ที่มีชุดบิตสูง (และดังนั้นจึงไม่มีไบต์เป็นส่วนหนึ่งของการเข้ารหัส UTF-8 แบบหลายไบต์สำหรับอักขระเดียวซึ่งอาจมีตัวผกผันด้านบน / ล่างแตกต่างกัน) หากคุณพบใด ๆ คุณสามารถถอยกลับไปที่เซนต์คิตส์และเนวิสสำหรับ 16 อันนี้หรือส่วนที่เหลือของสตริง
มีบางภาษาที่toupper()
หรือtolower()
ที่ตัวละครบางตัวในช่วง ASCII สร้างตัวละครที่อยู่นอกช่วงนั้นโดยเฉพาะอย่างยิ่งภาษาตุรกีที่ซึ่งฉัน and ıและİ↔ i ในพื้นที่เหล่านั้นคุณต้องมีการตรวจสอบที่ซับซ้อนกว่านี้หรืออาจไม่พยายามใช้การเพิ่มประสิทธิภาพนี้เลย
แต่ในบางกรณีคุณได้รับอนุญาตให้สมมติ ASCII แทน UTF-8 เช่นยูทิลิตี Unix ที่มีLANG=C
(โลแคล POSIX) ไม่ใช่en_CA.UTF-8
หรืออะไรก็ตาม
แต่ถ้าคุณสามารถตรวจสอบว่ามันปลอดภัยที่คุณสามารถtoupper
สตริงยาวปานกลางเร็วกว่าการเรียกร้องtoupper()
ในวง (ชอบ 5x) และครั้งสุดท้ายที่ฉันทดสอบกับ Boost 1.58มากมากเร็วกว่าboost::to_upper_copy<char*, std::string>()
ซึ่งไม่โง่dynamic_cast
สำหรับตัวละครทุกตัว
@
ลงใน^ 32
`โดยใช้