定界符 (\left \right)

\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

latex
\[
  \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 / Close25.77087 pt — 基准
\bigl( x \bigr)Open / Close27.15979 pt — 增加的只是字形
\left( x \right)Inner27.4375 pt — 多出 3 mu 的细空
\big( x \big)Ord28.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。

latex
\[
  \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
\big8.5 pt8.5 + 3.5 = 12 pt
\Big11.5 pt11.5 + 6.5 = 18 pt
\bigg14.5 pt14.5 + 9.5 = 24 pt
\Bigg17.5 pt17.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.」。有两种绕开的办法,两种都已实测可以编译通过

latex
\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.

latex
\[
  \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,正是这句话的直接后果。

latex
\[
  \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。

document.tex
\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 起步