小文字と大文字のアルファベット範囲は%32
、ASCIIコーディングシステムの「配置」境界を超えません。
このため0x20
、同じ文字の大文字と小文字のバージョンの違いはビットだけです。
これが当てはまらない場合は、0x20
トグルするだけでなく、を加算または減算する必要があります。一部の文字では、他の上位ビットを反転するためのキャリーアウトがあります。(また、トグルできる単一の操作はありません。また、lcaseを強制的に| = 0x20できないため、最初にアルファベット文字をチェックすることは困難です。)
関連するASCIIのみのトリック:小文字で強制的に小文字のASCII文字c |= 0x20
をチェックしてから、(符号なし)かどうかをチェックできc - 'a' <= ('z'-'a')
ます。つまり、3つの演算:定数25に対するOR + SUB + CMPです。もちろん、コンパイラーは(c>='a' && c<='z')
このようにasmに最適化する方法を知っているので、多くてもc|=0x20
自分で行う必要があります。必要なキャストをすべて自分で行うのは、特にデフォルトの整数の昇格をsignedに回避するのはかなり不便です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配列にアクセスして小文字を大文字に、またはその逆に変更する方法
(SIMD組み込み関数を使用したC、およびアルファベットのASCII文字用のスカラーx86 asmケースフリップ、その他は変更せずに残します)。
これらのトリックは、SIMD(SSE2やNEONなど)でテキスト処理を手動で最適化する場合にのみ役立ちます。 char
、ベクター内のどのsにも上位ビットが設定されて。(したがって、どのバイトも、単一の文字のマルチバイトUTF-8エンコーディングの一部ではありません。大文字と小文字の逆が異なる場合があります)。見つかった場合は、この16バイトのチャンクまたは文字列の残りのスカラーにフォールバックできます。
一部のロケールでは、ASCII範囲の一部の文字toupper()
またはtolower()
その一部でその範囲外の文字が生成されます。特にトルコ語では、I Iıおよびİ↔iです。 これらのロケールでは、より高度なチェックが必要になるか、この最適化をまったく使用しないようにする必要があります。
しかし、場合によっては、UTF-8の代わりにASCIIを使用することが許可されていLANG=C
ますen_CA.UTF-8
。
あなたはそれが安全で確認することができる場合でも、あなたはできるtoupper
ミディアムの長さの文字列をずっと速く呼び出すよりtoupper()
(5倍のような)ループの中で、そして最後に私はブースト1.58でテストずっと、ずっと速くよりもboost::to_upper_copy<char*, std::string>()
愚かをしているdynamic_cast
すべての文字のために。
@
して `に変換できます^ 32
。