I’ve needed to use double-struck capital letters lately, also called blackboard bold. There are a few quirks in how they are represented in Unicode and in HTML entities, so I’m leaving some notes for myself here and for anyone else who might need to look this up.
Unicode
The double-struck capital letters are split into two blocks for historical reasons. The double-struck capital letters used most often in math — ℂ, ℍ, ℕ, ℙ, ℚ, ℝ, ℤ — are located in the U+21XX range, while the rest are in the U+1D5XX range.
Low characters
The letters in the U+21XX range were the first to be included in the Unicode standard. There’s no significance to the code points.
ℂ U+2102 ℍ U+210D ℕ U+2115 ℙ U+2119 ℚ U+211A ℝ U+211D ℤ U+2124
The names, however are consistent. The official name of ℂ is
DOUBLE-STRUCK CAPITAL C
and the rest are analogous.
High characters
The code point for double-struck capital A is U+1D538 and the rest are in alphabetical order: the nth letter of the English alphabet has code point
0x1D537 + n.
However, the codes corresponding to the letters in the low range are missing. For example, U+1D53A, the code that would logically be the code for ℂ, is unused so as not to duplicate the codes in the low range.
The official names of these characters are
MATHEMATICAL DOUBLE-STRUCK CAPITAL C
and so forth. Note the “MATHEMTICAL” prefix that the letters in the low range do not have.
Incidentally, X is the 24th letter, so the new logo for Twitter has code point U+1D54F.
HTML Entities
All double-struck letters have HTML shortcuts of the form *opf;
where *
is the letter, whether capital or lower case. For example, is 𝔸
and is 𝕒
.
The letters with lower Unicode values also have semantic entities as well.
ℂ ℂ ℂ ℍ ℍ ℍ ℕ ℕ ℕ ℙ ℙ ℙ ℚ ℚ ℚ ℝ ℝ ℝ ℤ ℤ ℤ
LaTeX
The LaTeX command for any double-struck capital letter is \mathbb{}
. This only applies to capital letters.
Python
Here’s Python code to illustrate the discussion of Unicode values above.
def doublestrike(ch): exceptions = { 'C' : 0x2102, 'H' : 0x210D, 'N' : 0x2115, 'P' : 0x2119, 'Q' : 0x211A, 'R' : 0x211D, 'Z' : 0x2124 } if ch in exceptions: codepoint = exceptions[ch] else: codepoint = 0x1D538 + ord(ch) - ord('A') print(chr(codepoint), f"U+{format(codepoint, 'X')}") for n in range(ord('A'), ord('Z')+1): doublestrike(chr(n))
Fun python trick: rename “exceptions” to “codepoints” and do
codepoint = codepoints.get(ch, 0x1D538 + ord(ch) – ord(‘A’))