【发布时间】:2012-01-15 08:28:11
【问题描述】:
如果 unicode 使用 17 位代码点,代理对如何从代码点计算?
【问题讨论】:
-
什么意思? Unicode 代码点不是 17 位,并且 UTF-8 不使用代理对。
-
Unicode 代码点大约需要 21 位。它虽然使用了每个 65536 个代码点的 17 个平面,但总共有 1114112 个代码点。大约是 20.087 位。
如果 unicode 使用 17 位代码点,代理对如何从代码点计算?
【问题讨论】:
Unicode 代码点是范围从 0x000000 到 0x10FFFF 的标量值。因此它们是 21 位整数,而不是 17 位。
代理对是 UTF-16 形式的一种机制。这将 21 位标量值表示为一个或两个 16 位代码单元。
Unicode 联盟的常见问题解答UTF-8, UTF-16, UTF-32 & BOM 中通过示例代码对此进行了详细说明。该常见问题解答指的是 Unicode 标准中包含更多详细信息的部分。
【讨论】:
如果是您所追求的代码,以下是单个代码点分别以 UTF-16 和 UTF-8 编码的方式。
UTF-16 代码单元的单个代码点:
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));
}
UTF-8 代码单元的单个代码点:
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);
}
【讨论】: