prize18-4 Exercise 1: Surrogate Pairs by Hand =============================================== Method for U+1F600: 0x1F600 - 0x10000 = 0x0F600 = 0000 1111 0110 0000 0000 (20 bits). Top 10 bits 0000111101 = 0x03D, so high surrogate = 0xD800 + 0x3D = 0xD83D. Bottom 10 bits 1000000000 = 0x200, so low surrogate = 0xDC00 + 0x200 = 0xDE00. Pair: D83D DE00. ex1.py: def to_surrogates(cp): v = cp - 0x10000 return 0xD800 + (v >> 10), 0xDC00 + (v & 0x3FF) for cp in [0x1F600, 0x24B62]: v = cp - 0x10000 hi, lo = to_surrogates(cp) print(f"U+{cp:X}: minus 0x10000 = {v:#07x} = {v:020b}") print(f" top 10 bits {v >> 10:010b}, low 10 bits {v & 0x3FF:010b}") print(f" pair {hi:04X} {lo:04X}") print(" Python:", chr(cp).encode("utf-16-be").hex(" ")) Real output (Python 3.14): U+1F600: minus 0x10000 = 0x0f600 = 00001111011000000000 top 10 bits 0000111101, low 10 bits 1000000000 pair D83D DE00 Python: d8 3d de 00 U+24B62: minus 0x10000 = 0x14b62 = 00010100101101100010 top 10 bits 0001010010, low 10 bits 1101100010 pair D852 DF62 Python: d8 52 df 62 Both match. Every high surrogate lies in D800-DBFF and every low one in DC00-DFFF, because 10 bits can add at most 0x3FF to the base.