2012-01-15 15 views
1

ユニコードが17ビットコードポイントを使用する場合、サロゲートペアはコードポイントからどのように計算されますか?サロゲートペアはどのように計算されますか?

+1

あなたは何を意味するのですか? Unicodeコードポイントは17ビットではなく、UTF-8はサロゲートペアを使用しません。 – kennytm

+0

Unicodeコードポイントには約21ビットが必要です。それにもかかわらず、各65536コードポイントの17プレーンを使用すると、合計1114112コードポイントになります。約20.087ビットです。 – dalle

答えて

7

Unicodeコードポイントは、0x000000から0x10FFFFの範囲のスカラー値です。つまり、17ビットではなく、21ビットの整数です。

サロゲートペアは、UTF-16形式のメカニズムです。これは、21ビットのスカラ値を1つまたは2つの16ビットコード単位として表します。

  • 0x000000から0x00FFFFまでのスカラー値は、0x0000から0xFFFFまでの単一の16ビットコード単位で表されます。
  • 0x00D800から0x00DFFFまでのスカラー値は、Unicodeでは文字ではないため、Unicode文字列では決して発生しません。
  • 0x010000から0x10FFFFまでのスカラー値は2つの16ビットコード単位で表されます。第1のコードユニットは、0xD800-0xDBFFの範囲のコード単位として、スカラー値の上位11ビットをコード化する。 0x01〜0x10の値を4ビットでエンコードするのはちょっと難しいことです。第2のコードユニットは、0xDC00-0xDFFFの範囲のコード単位として、スカラー値の下位10ビットをコード化する。

これについては、サンプルコードとともに、Unicodeコンソーシアムのよくある質問UTF-8, UTF-16, UTF-32 & BOMで詳しく説明しています。そのFAQは、Unicode Standardのセクションを参照しています。

+1

FAQのサンプルコードでは、サロゲートペアをコードポイントにマッピングする方法について説明しています。問題は逆方向マッピングに関するものでした。これは、Unicode標準の第3章のD91(http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf –

+0

+1)に示されています。 – dalle

+0

@ JukkaK.Korpela、よくある質問を読む[Q:UTF-16から文字コードに変換するアルゴリズムとは何ですか?](http://www.unicode.org/faq//utf_bom.html#utf16-3)私は文字コードからUTF-16へのマッピングとサンプルコードの両方を再び見ることができますが、タイトルはそれを約束しません。 –

4

あなたが後にあるコードの場合、ここでは単一のコードポイントがそれぞれUTF-16とUTF-8でエンコードされる方法があります。

UTF-16 codeunitsへの単一のコードポイント:UTF-8 codeunitsへ

if (cp < 0x10000u) 
{ 
    *out++ = static_cast<uint16_t>(cp); 
} 
else 
{ 
    *out++ = static_cast<uint16_t>(0xd800u + (((cp - 0x10000u) >> 10) & 0x3ffu)); 
    *out++ = static_cast<uint16_t>(0xdc00u + ((cp - 0x10000u) & 0x3ffu)); 
} 

単一のコードポイント:

if (cp < 0x80u) 
{ 
    *out++ = static_cast<uint8_t>(cp); 
} 
else if (cp < 0x800u) 
{ 
    *out++ = static_cast<uint8_t>((cp >> 6) & 0x1fu | 0xc0u); 
    *out++ = static_cast<uint8_t>((cp & 0x3fu) | 0x80u); 
} 
else if (cp < 0x10000u) 
{ 
    *out++ = static_cast<uint8_t>((cp >> 12) & 0x0fu | 0xe0u); 
    *out++ = static_cast<uint8_t>(((cp >> 6) & 0x3fu) | 0x80u); 
    *out++ = static_cast<uint8_t>((cp & 0x3fu) | 0x80u); 
} 
else 
{ 
    *out++ = static_cast<uint8_t>((cp >> 18) & 0x07u | 0xf0u); 
    *out++ = static_cast<uint8_t>(((cp >> 12) & 0x3fu) | 0x80u); 
    *out++ = static_cast<uint8_t>(((cp >> 6) & 0x3fu) | 0x80u); 
    *out++ = static_cast<uint8_t>((cp & 0x3fu) | 0x80u); 
} 
関連する問題