\sin\left(x\right) 和 \sin(x) 看上去是同一个公式,宽度却不同。用 TeX Live 2024 的 pdfLaTeX 测量,前者是 27.4375 pt,后者是 25.77087 pt。相差的 1.66663 pt 来自这样一件事:LaTeX 把 \left 与 \right 之间的内容当作 Inner(内层)原子,而 Inner 原子前面要加 3 mu 的细空。LaTeX 的定界符有两个系列——自动的 \left \right,以及手动挑选的四级 \big \Big \bigg \Bigg——人人都会遇到的两件烦心事,“括号太大”和“\left\right 里不能换行”,根子都在于你选了哪一个系列。本页用测量数据来定这个选择。
\left … \right 是怎样决定大小的
它并不是精确拉伸到内容的高度,而是 从字体预备的几档括号中,挑出跨过门槛的最小一档。门槛由两个参数决定,在 TeX Live 2024 的 LaTeX 中,\delimiterfactor 为 901,\delimitershortfall 为 5 pt:括号至少要覆盖所需高度的 90.1 %,或者比所需高度矮不超过 5 pt——两者取较宽松的一个。\left 或 \right 后面紧跟的字符才是真正的定界符:圆括号用 ( ),方括号用 [ ],花括号用 \{ \},尖括号用 \langle \rangle。
\[
\left( \frac{a^2 + b^2}{c^2} \right)
\qquad
\left[ \sum_{k=1}^{n} \frac{1}{k} \right]
\qquad
\left( a, b \right]
\]这个门槛就是“括号太大”的真相。在 10 pt 的 article 中,把被包围材料的高度一点点抬高:到 9 pt 为止,12 pt 的括号(与 \big 同一档)就够用;一旦到了 10 pt,选择就 直接跳到 18 pt 的括号,也就是 \Big 那一档;抬到 12 pt 仍然是同一个 18 pt。因为档位是离散的,内容只高了一点点,括号看上去就大了一整级。还有一点自由度:配对的定界符 不必是同一种。像 \left( a, b \right] 这样的半开区间就是这么写的。
\left…\right 与 \bigl…\bigr 的区别:间距会变
风格指南说“固定大小时优先用 \bigl…\bigr 而非 \left…\right”,这不是口味问题,而是存在 可测量的差异。TeX 给公式中的每个元素分配一个「原子(atom)」类别,并按类别的组合决定前后间距。\left … \right 的结果是 Inner,\bigl 给出 Open(开),\bigr 给出 Close(闭),而裸的 \big 给出 Ord(普通符号)。函数名如 \sin 是 Op(算子);Op 后面接 Open 完全不加空白,接 Ord 或 Inner 则加 3 mu 的细空——这正是开头那 1.66663 pt。
| 写法 | 原子类别 | \sin…(x) 的实测宽度 |
|---|---|---|
( x ) | Open / Close | 25.77087 pt — 基准 |
\bigl( x \bigr) | Open / Close | 27.15979 pt — 增加的只是字形 |
\left( x \right) | Inner | 27.4375 pt — 多出 3 mu 的细空 |
\big( x \big) | Ord | 28.82642 pt — Op→Ord 同样加 3 mu |
表格的最后一行说明了为什么不该嫌 \bigl/\bigr 麻烦。裸的 \big( 是 Ord,因此比 \bigl( 宽 1.66663 pt——正好一个细空。打开 latex.ltx,这个区分各占朴素的一行:\bigl 是 \mathopen\big,\bigr 是 \mathclose\big,而 \bigm 是 \mathrel\big。字母分别取自 left、right、middle,所以 \bigm 造出的不是括号,而是与括号同样大小的关系符。集合描述法中的竖线 \bigm| 就是典型用法,实测两侧各加 5 mu 的粗空,合计 5.55542 pt。
\[
\sin\bigl( x \bigr) % Open/Close: no stray space
\qquad
\biggl\{\, x \bigm| x > 0 \,\biggr\}
\qquad
\bigl( \Bigl[ \,\cdots\, \Bigr] \bigr)
\]\big \Big \bigg \Bigg 的实际尺寸——以及 12 pt 文档里 \big 为何没效果
这四个大小是 以绝对长度写死的。fontmath.ltx 里的定义各占一行,都是用 \left … \right 包住一个不可见的盒子:\big 是 8.5 pt,\Big 是 11.5 pt,\bigg 是 14.5 pt,\Bigg 是 17.5 pt。单位是 pt 而不是 em,所以 改变正文字号并不会改变所要求的高度。于是在 10 pt 的 article 中,( 是 10 pt、\big( 是 12 pt,差别看得见;可一旦加上 12pt 类选项,普通的 ( 本身就已经是 12 pt 高,此时 \big( 量得高 9.0 pt、深 3.0 pt——与素的 ( 完全一致。这就是“我写了 \big 却什么也没变”的答案:12 pt 文档请从 \Big 起步。
| 命令 | fontmath.ltx 中要求的高度 | 10pt article 实测(高 + 深) |
|---|---|---|
( | —(字体的普通字形) | 7.5 + 2.5 = 10 pt |
\big | 8.5 pt | 8.5 + 3.5 = 12 pt |
\Big | 11.5 pt | 11.5 + 6.5 = 18 pt |
\bigg | 14.5 pt | 14.5 + 9.5 = 24 pt |
\Bigg | 17.5 pt | 17.5 + 12.5 = 30 pt |
每一档的深都比高小 5 pt,是因为定界符相对于 公式的轴线(axis) 上下对称摆放。在标准的 10 pt 数学字体中,轴线在基线上方 2.5 pt,所以 12 pt 的括号就分成上 8.5 pt、下 3.5 pt。手动选择大小的实务理由有三:要让多行的高度一致(\left … \right 逐行测量内容,一叠公式的括号高度会参差不齐)、不希望被推到大一号,以及 想自己决定两侧的空白。反过来,对于高度难以预料的一次性公式,\left … \right 更快也更保险。
\left\right 里不能换行——会发生什么,又该怎么绕开
\left … \right 会形成一个组,所以在其内部写 \\ 会让编译停下。在 align 环境里试一下,TeX Live 2024 的 pdfLaTeX 会说:! Extra }, or forgotten \right.,接着是 ! Missing \right. inserted.。前一句的意思是「\right 还没来,行就结束了」,后一句是「于是替你补上了一个 \right.」。有两种绕开的办法,两种都已实测可以编译通过。
\begin{align}
% 1. fixed manual sizes: close and reopen, same size on both lines
a &= \biggl( b + c \notag\\
&\qquad + d \biggr)\\
% 2. null delimiters: end each fragment with \right. and reopen with \left.
e &= \left( f + g \right. \notag\\
&\qquad \left. + h \right)
\end{align}第一种用手动大小固定括号,并在行末与行首各自完成闭与开;两行的括号处于同一档,看上去也就整齐。第二种用下一节的不可见定界符:每个片段以 \right. 收尾,再用 \left. 重新开启。这样仍是自动大小,但 由于每行各自测量,左右括号的高度可能不一致。当长公式要跨越分数或求和换行时,第一种固定手动大小更实用。分数与矩阵本身如何换行,留给各自的专页。
! Missing \right. inserted. 与 ! Extra \right.
这两条报告的是配对被破坏,并且分别说明 缺的是哪一侧。写了 \left 却没写 \right 就结束公式,会得到 ! Missing \right. inserted.——这是 LaTeX 补了一个 \right. 想继续走下去的信号。反过来,只出现 \right) 而没有 \left,则是 ! Extra \right.。前一种情形还会连带引出 ! LaTeX Error: Bad math environment delimiter. 和 ! Missing $ inserted.,所以最快的办法是 回到最上面那条错误,数一数 \left 的个数。
只在一侧显示括号:\left. 与 \right.
在 \left 或 \right 后面紧跟一个 句点 .,那一侧就什么也不画。. 被当作「不绘制任何东西的定界符」(null delimiter):它满足成对规则,然后隐去身形。最常见的用途是 求值竖线:\left. \frac{dy}{dx} \right|_{x=0} 让左侧留空,只把右侧的竖线拉伸到内容高度,并在右下角写上条件。定积分的 \left. \frac{x^3}{3} \right|_{0}^{1} 也是同一形状。若用手动大小,甚至连配对的 \left 都不需要:f(x) \bigr|_{0}^{1} 可以独立成立。反过来,若完全不想显示定界符却仍要这个组,就把两侧都写成 .——\left. … \right.。
\[
\left. \frac{dy}{dx} \right|_{x=0}
\qquad
\left. \frac{x^3}{3} \right|_{0}^{1}
\qquad
f(x) \bigr|_{0}^{1} % fixed size, no \left needed
\]\middle:插入与括号同高的分隔线
在 \left 与 \right 之间写 \middle 再接一个定界符,可以插入任意多条 与外层同高的分隔线。集合描述法 \left\{ x \;\middle|\; \dots \right\} 就是典型例子。这个命令并不在高德纳最初的 TeX 里,而是 e-TeX 添加的扩展(TeX Live 2024 的 pdfLaTeX 报告 \eTeXversion 为 2)。而且 e-TeX 手册明确写道,\right 会「向当前列表追加一个 Inner atom」。本页开头那 3 mu,正是这句话的直接后果。
\[
\left\{\, x \in \mathbb{R} \;\middle|\; x^2 < \frac{1}{2} \,\right\}
\qquad
\biggl\{\, x \bigm| x^2 < 1 \,\biggr\}
\]这里有个陷阱。按 e-TeX 手册,\middle 右侧的材料是「按左定界符之后」来排的——也就是说,\middle| 表现为一个开定界符,两侧完全不加空白。实测也吻合:\left(a\middle| -b\right) 为 27.91093 pt,与 \left(a\mathopen{|} -b\right) 完全相同,比 \mathord 版窄 4.44434 pt。所以竖线两侧要自己留空:写成 \;\middle|\;,或用 \mathrel{}\middle|\mathrel{} 把它包成关系符。后者在两侧各加 5 mu 的粗空(合计 5.55542 pt),恰好与 \bigm| 的间距一致。如果不是非用 \middle 不可,\bigm| 本来就更短。
定界符一览:\langle、\lceil、\lfloor、\| 与 \Vert
只有字体备有「可伸长部件」的符号,才能跟在 \left/\right 或 \big 一族之后。圆括号、方括号和斜杠可以直接从键盘打出,但 { } 是 LaTeX 的保留字符,要作为花括号定界符就得写 \{ \}。尖括号请用 \langle \rangle,不要用键盘上的 < >:后者是不等号,也就是关系符,两侧会加粗空,根本不像定界符。实测:\langle a,b\rangle 为 21.79976 pt,而 <a,b> 膨胀到 35.13298 pt——宽了 13 pt 以上。
| 命令 | 字形 | 用途 / 注意 |
|---|---|---|
( ) | ( ) | 直接输入;最常用的一对 |
[ ] \lbrack \rbrack | [ ] | 直接输入;\lbrack \rbrack 等价 |
\{ \} | { } | { } 是保留字符;必须加反斜杠 |
\langle \rangle | ⟨ ⟩ | 内积、狄拉克记号;不要用 < > |
| \vert | | | 绝对值等;两者都是 Ord——成对请用 \lvert/\rvert |
\| \Vert | ‖ | 范数等;输出完全相同,都是 Ord |
\lvert \rvert | | | | amsmath;一对正确的 Open/Close |
\lVert \rVert | ‖ ‖ | amsmath;范数应当用这一对 |
\lceil \rceil | ⌈ ⌉ | 上取整(天花板函数) |
\lfloor \rfloor | ⌊ ⌋ | 下取整(地板函数) |
\backslash / | \ / | 商集等;可写成 \left\backslash … \right/ |
\uparrow \downarrow | ↑ ↓ | 双线为 \Uparrow \Downarrow;双向为 \updownarrow |
\lgroup \rgroup | ⟮ ⟯ | 圆润的大号括号;适合大型陈列式 |
\lmoustache \rmoustache | ⎰ ⎱ | 大花括号的上半与下半 |
\arrowvert \bracevert | │ ⎪ | 用于延长箭头与花括号的竖直部件 |
绝对值与范数:|x| 为何出事,以及 \DeclarePairedDelimiter
| 与 \| 都是 Ord(普通符号),从不表明自己是开还是闭。代价在 |-x| 上表现得最刺眼:实测 23.49298 pt,而 \lvert -x \rvert 是 19.04865 pt。相差的 4.44433 pt,正是紧跟 Ord 的 - 被解读为 二元运算符,从而在两侧各带来 4 mu 的中空。\lvert 是 Open,其后的同一个 - 就成了一元负号,不带任何空白。函数名之后也一样:\sin|x| 比 \sin\lvert x\rvert 宽出一个细空(3 mu)。请使用 amsmath 的 \lvert/\rvert,范数则用 \lVert/\rVert。\| 与 \Vert 的输出完全一致,选哪个都改变不了这个问题。
话虽如此,每次都敲 \left\lvert … \right\rvert 并不现实。若同一记法要反复使用,正确答案是 mathtools 的 \DeclarePairedDelimiter。在导言区定义一次,正文里就写 \abs{x};要随内容伸长写 \abs*{\frac{a}{b}};要固定某一档写 \abs[\big]{x}。更妙的是,它生成的带星形式被包成 \mathopen{}\mathclose\bgroup … \aftergroup\egroup,因此 用了 \left … \right 却不会变成 Inner atom——实测 \sin\abs*{x} 为 23.54865 pt,与 \sin\lvert x\rvert 完全相同。宏包替你抵消了本页开头那 1.66663 pt。
\usepackage{mathtools}
\DeclarePairedDelimiter{\abs}{\lvert}{\rvert}
\DeclarePairedDelimiter{\norm}{\lVert}{\rVert}
% in the body:
\[
\abs{x} \le \abs*{\frac{a}{b}}, \qquad
\norm*{\frac{v}{2}}, \qquad \abs[\big]{y}
\]- 高度难以预料的一次性公式 →
\left…\right,又快又稳 - 要让多行括号一致,或要正确的间距 →
\bigl\Bigl\biggl\Biggl及对应的r版 - 在括号之间放一条竖线 →
\bigm|,或\;\middle|\; - 只显示一侧(求值竖线) →
\left. … \right| - 同一记法反复使用 → mathtools 的
\DeclarePairedDelimiter - 12 pt 文档里
\big没效果 → 普通括号本就已是 12 pt;请从\Big起步