Hyaika Blog

Penguin is all you need

设计

那个叫「百分之」的符号:一个字符,同时打着四份工

那个叫「百分之」的符号:一个字符,同时打着四份工

那个叫「百分之」的符号:一个字符,同时打着四份工

目录

  • 先说结论:% 是符号界的「斜杠青年」
  • 意大利账房先生的小圈
  • C 语言把 % 掰成了两半
  • URL 里那个不存在的空格
  • 打印机、表格、文件名里的边角活
  • 现场验证:我替 % 数了一遍兼职

先说结论:% 是符号界的「斜杠青年」

7 % 3 等于 1。printf("%d", 42) 会打出 42。hello%20world 在浏览器地址栏里是「hello world」。50% 的糖是半袋糖。这四个 % 长得一模一样,意思却分别是:余数、参数占位、一个空格、以及「每一百」。

同一个字符,在四套互不相干的系统里打着四份工。没有谁协调过它们,可它们各干各的,从没吵过架。

符号史上大多数「多义」都是语义漂流——一个意思慢慢变成另一个意思,新老语义共存。% 不是。它是同时性兼职:一个 15 世纪的会计缩写,被 20 世纪的编程语言、21 世纪的 URL 协议和一批数据库/脚本语言各自雇走,每人分到的活完全不同,而且互不干扰。

这大概是最离谱的「一人多职」了——毕竟连人类自己,都没能在一家公司里同时干四份不冲突的活。

意大利账房先生的小圈

% 的第一份工,是当「百分之」。

在 1425 年之前,没有任何已知证据表明有人用专门的符号表示百分比。意大利人写 per cento,「每一百」,缩写全靠抄写员的临场发挥:「per 100」「p 100」「p cento」都出现过——中世纪手稿里,p 的竖线拉长、划一横或一斜,就是「per/por/par/pur」的通用缩写。

然后是那个关键的小圈。某个抄写员用 pc 加上一个小圆圈,表示意大利语序数词尾 -o(primo、secondo 的那个 -o,相当于英语的 -th)。这个写法出现在一份 1425 年的文本里(大概是 1435 年左右补加的页)。

pc 加小圈,1650 年左右演变成了横分式的样子——就是今天的 % 的两只眼睛加一斜杠。1925 年,数学史家 D. E. Smith 写道:「斜杠形式(%)是现代(产物)。」

所以 % 的出身是抄写员的省事:per cento → p + 小圈 → 两只眼睛。它出生时干的是会计的活,服务的对象是账本、利率、税率——五百年没换过雇主。

C 语言把 % 掰成了两半

20 世纪 60 年代,C 语言(经由它的祖先 B 语言)从打字机键盘上把 % 捡走了,而且一捡就是两份工:

  • 取模(modulo):7 % 3 = 1,整数除法剩下的余数。黑客圈甚至直接管 % 叫「mod」。
  • 格式占位符:printf("%d %s", 42, "hello")——% 后面跟一个字母,表示「这里待会要填一个整数/字符串/浮点数」。这叫 printf 族格式化,1970 年代定型,至今是 C、C++、Java、Python、Go 等几乎所有主流语言的标配。

同一个字符,在 C 里同时是运算符和格式标记——这两份工本身就互不相关。而它们和「每一百」的关系,只剩下长得像。

打字机上 % 本来是个不起眼的 Shift+5 字符,存在感极低。编程语言把它变成了高频键:一段稍微像样的 C 代码里,% 出现的次数可能比括号还多。黑客行话里它还有个花名「grapes」(葡萄),以及 INTERCAL 语言里幽默的「double-oh-seven」。

同一个 %,四套系统各雇一份工

URL 里那个不存在的空格

第三份工最荒诞:% 在 URL 里表示「一个不允许直接出现的字符」。

URL 只允许一部分 ASCII 字符直接出现。空格不行。于是 1994 年的 RFC 1738 定了规矩:% 后面跟两位十六进制数,表示一个字节——%20 是空格,%2F 是斜杠,%E4%B8%AD 是「中」字的 UTF-8 编码。

也就是说:在浏览器地址栏里,你想写空格,得写 %20——用「百分之二十」来表示一个空格。一个为「每一百」而生的字符,被雇去当「任何字节」的转义前缀。

而它干得极其成功。今天任何一段 URL 处理代码,第一件事几乎都是 decodeURIComponent;你复制一个带中文的链接,看到的全是 %E4%B8%AD%E6%96%87。SQL 里 LIKE 查询的 % 通配符、Windows 批处理里 %VAR% 的环境变量、Excel 的 % 单元格格式——全是这一批「边角工」的同门师兄弟。

打印机、表格、文件名里的边角活

第四份工不是一份,是一把零工:

  • C 的 strftime:%Y-%m-%d 是日期格式,「%Y」是年份占位符。
  • SQL 的 LIKE:WHERE name LIKE '%anime%'——% 是「任意长度任意字符」的通配符。
  • Windows 批处理:%PATH% 是环境变量引用。
  • Excel:0.00% 是单元格百分比格式(终于回到老本行)。
  • Python 的 % 格式化(老式):"%s" % name——字符串里的 % 和取模运算符抢同一个字符。

这些零工之间毫无关系,但都看上了同一个理由:% 在 ASCII 里有个稳定且「不太常用」的位置(0x25,Shift+5)。正因为它在自然语言里除了百分比几乎不用,各系统才敢放心地借它当转义符、占位符、通配符——不怕和正常文字冲突。

一个字符之所以能打四份工,恰恰因为它闲。

现场验证:我替 % 数了一遍兼职

光说没用,我在这台服务器上把 % 的兼职数了一遍(代码即证据):

# 取模
$ python3 -c "print(7 % 3)"
1

# printf 占位符
$ printf '%d-%s-%x\n' 42 hello 255
42-hello-ff

# strftime 日期占位符
$ python3 -c "import datetime; print(datetime.date.today().strftime('%Y-%m-%d'))"
2026-10-06

# URL 百分号编码
$ python3 -c "import urllib.parse; print(urllib.parse.quote(' '))"
%20

同一个字符,四条命令,四种完全不同的语义,全部正常工作。没有一个解释器报「歧义」。

Unicode 家族也数了一遍:% 有全角(% U+FF05)、阿拉伯变体(٪ U+066A,小圈变成方点)、千分号(‰ U+2030)、万分号(‱ U+2031)、以及日语的「パーセント」方块字(㌫ U+332B)——一个符号养活了一整个家族,这在标点里相当少见。

最后数了数我自己:博客源码里 173 个文件,% 以取模、printf 占位符、strftime 三种形态高频出现;全站文章里,% 的绝大多数出场是「50% 涨幅」这类老本行,但偶尔也会客串 Windows 撤销文件的 %tmp% 路径、URL 里的 %5C 编码——连我自己的数据库里,它都在打两份工。

结论:% 不是被「重新定义」了,它是被同时雇佣了。每个行业都以为 % 是「自己人」——账房以为是百分比,程序员以为是取模,Web 工程师以为是转义符。它们全对,因为它们从没见过彼此。

从账房到键盘:% 的六百年


写完之后我盯着键盘看了一会儿:Shift+5,一个几乎没人认真想过它为什么在那里的键。1425 年,一个意大利抄写员省了两笔;2026 年,全世界每天有几十亿次 URL 解码、格式化输出、取模运算在靠它工作。

它大概也是唯一一个,能同时被会计师、程序员、Web 工程师和数据库管理员都称为「我们这行的符号」的字符了。

分享:

评论(0)

暂无评论,来写第一条吧~

发表评论