0
0

More than 1 year has passed since last update.

Math.clz32という標準関数を、UTF-8の処理に使ってみた話です。

Math.clz32とは

clzはCount Leading Zeros(先頭にある0の数を数える)の略で、その名の通り、引数を32ビット符号なし整数として、先頭に入る0の個数を数える関数です。

ARMやx64にも搭載されるなどメジャーで高速に実行可能な演算で、他のビット操作を構築する要素としても使えるとのことです。

UTF-8のビットパターン

UTF-8はマルチバイトの文字コードですが、シフトJISで起きた「ダメ文字」(2バイト目にASCIIの範囲まで使っていたことで、ASCIIとしての処理が行われて誤作動する)などの問題を避ける、そして文字の区切りをはっきりさせるために、バイトごとのビットパターンによって使われる場所をはっきり区分けしています1

16進 ビットパターン 役割
0x00 - 0x7F 0xxxxxxx 1バイト文字
0x80 - 0xBF 10xxxxxx マルチバイト文字の2バイト目以降
0xC0 - 0xDF 110xxxxx 2バイト文字の1バイト目
0xE0 - 0xEF 1110xxxx 3バイト文字の1バイト目
0xF0 - 0xF7 11110xxx 4バイト文字の1バイト目
0xF8 - 0xFF 11111xxx 未使用

ご覧のように、「先頭に続く1の数」でバイトの種類を判定しています。

Math.clz32で計算

0xFFとのXORを取れば、0は1に、1は0に反転するので、Math.clz32で処理するのにふさわしい形となります。そして、上位24ビットは0なので、Math.clz32(value ^ 0xFF) - 24とすれば、使いやすい値が取れます。特に、2~4がそのまま取れるのも便利なところです。

16進 ビットパターン 演算結果 役割
0x00 - 0x7F 0xxxxxxx 0 1バイト文字
0x80 - 0xBF 10xxxxxx 1 マルチバイト文字の2バイト目以降
0xC0 - 0xDF 110xxxxx 2 2バイト文字の1バイト目
0xE0 - 0xEF 1110xxxx 3 3バイト文字の1バイト目
0xF0 - 0xF7 11110xxx 4 4バイト文字の1バイト目
0xF8 - 0xFF 11111xxx 5以上 未使用

外部リンク

  1. この表はビットパターンだけ表すために簡略化したもので、0xC0、0xC1、0xF5-0xF7は正当なUTF-8には登場しません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0