数学技巧

大多数时候,LaTeX 会按照你写下的内容把公式排得很漂亮。但偶尔仍会留下细小瑕疵:分数里的根号太高,把行距撑开;相邻平方根的顶线对不齐;求和号下方的长条件让左右空白变宽。为修正这些“最后一点”的问题,有一组小而锋利的工具。本页以问题 → 修正方法的形式汇总它们。深入说明放在各自的专题页面;这里的目标是快速查找:哪种视觉问题该用哪个命令。尤其会重点讲其他页面没有覆盖的 \smash

微调工具箱

这些工具背后有一个共同想法:把某个元素占据的尺寸(高度、深度、宽度)与它的外观分开来控制。如果可见的内容可以被当作“尺寸为零”,或者反过来,为不可见的内容预留空间,就能精确控制它对相邻元素和行距的影响。控制纵向尺寸(高度和深度)的是 \smash\vphantom\mathstrut;控制横向尺寸(宽度)的是 \mathrlap\mathllap\mathclap 和负空白 \!;同时控制两者的是 \phantom

它们都是微调印刷结果的最后一步,不会改变公式含义。因此基本原则是:先把数学内容正常写出来,只在确实出现问题的位置精准使用。下表是快速参考。

症状使用的命令来源
tall-pushes-lines高元素把行距撑开\smash\smash[t] / \smash[b]LaTeX 核心([tb] 来自 amsmath)
radical-heights-differ相邻根号或行的高度不一致\vphantom / \mathstrutLaTeX 核心
reserve-space为空白不可见内容预留位置以对齐\phantom / \hphantom / \vphantomLaTeX 核心
wide-subscript宽下标条件把列撑宽\mathclap\mathrlap / \mathllapmathtools
stack-symbol想把任意符号叠在 = 等上方\overset / \undersetamsmath
too-much-space符号之间距离过大\!(负细空白)LaTeX 核心

\smash — 让高度和深度按零计算

问题。 当分数的分子或分母中出现根号时,\sqrt 的顶端(根号符号的上边)会高出普通行。为了避免行与行相撞,LaTeX 会按这段额外高度扩大它与上一行的间距。结果是只有这一行行距变大,整页行距看起来不均匀。

修正方法。 \smash{...} 会把参数排成仿佛高度和深度都为零。可见内容(实际字形)仍照常印出,但 LaTeX 会把这个盒子视为纵向尺寸为零,因此不再决定扩大行距。LaTeX2e 官方参考也说明,如果不用 \smash,LaTeX 会把该行与上一行拉开,不均匀的行距可能难看;同时要注意,被压扁的内容也可能侵入上一行。

latex
% 問題:分数のなかの根号が、この行だけ行間を押し広げる
$y = \frac{1}{\sqrt{1 - x^2}}$

% 直し方:根号の高さをゼロ扱いにして行送りへの影響を消す
$y = \frac{1}{\smash{\sqrt{1 - x^2}}}$

两个公式看起来相同,但后者中 \sqrt{1-x^2} 的高度不会计入行距计算,因此该行会与前后行保持相同间隔。把较高元素放入正文中的行内公式时,这一点尤其有效。

加载 amsmath 后,\smash 会获得一个可选参数\smash[t]{...} 只压掉上方(top,高度),保留自然深度;\smash[b]{...} 只压掉下方(bottom,深度),保留高度。正如 amsmath 手册所说,有时确实需要只压掉某个内容的高度或深度,同时保留另一侧的自然尺寸。

amsmath 自身举出的典型例子,是对齐相邻平方根的高度。写成 \sqrt{x} + \sqrt{y} + \sqrt{z} 时,y 有向下伸出的部分,因此中间的根号看起来略微下沉。用 \smash[b] 只消除内容的深度,就能让三个根号对齐。

latex
% amsmath マニュアルの例:まんなかの根号だけ下がるのを直す
$\sqrt{x} + \sqrt{y} + \sqrt{z}$              % y の descender で不ぞろい
$\sqrt{x} + \sqrt{\smash[b]{y}} + \sqrt{z}$   % y の深さを消してそろえる

\smash 不仅能在数学模式中使用,也能在正文中使用;但在正文中它不会进入水平模式,因此若放在段落开头,需要在前面加 \leavevmode。注意,\smash 与下一节的 \vphantom相反操作\smash 把大的东西当作零,\vphantom 则给零宽可见内容以真实高度。实际上,amsmath 也展示了把二者组合使用来对齐高度的例子。

\vphantom\mathstrut — 用不可见高度对齐

问题。\smash 相反,有时你需要让较低的元素按较高的元素抬起来。例如把 \sqrt{a}\sqrt{a^2} 并排时,指数会让右侧根号更高,两个顶端无法对齐。分段公式或矩阵中各行内容高度不同时,也会出现同样问题。

修正方法。 \vphantom{...}(vertical phantom)会生成一个不可见盒子,它与参数有相同的高度和深度,但宽度为零。在较低的元素中放入“与较高内容相同的 \vphantom”,就能在不可见的情况下只对齐高度。不带参数的简便形式是 \mathstrut,它定义为 \vphantom(,也就是一个左圆括号高度的不可见支柱。把它放在各元素开头,就能把高度统一到一个左圆括号的高度。

latex
% 根号の天井をそろえる:各 \sqrt の中身に \mathstrut を足す
$\sqrt{\mathstrut a}\;\sqrt{\mathstrut a^2}\;\sqrt{\mathstrut b}$

% 任意の高さにそろえたいときは、揃え先の中身を \vphantom に渡す
$\sqrt{a} \;\sqrt{\vphantom{a^2}\,a}$

这些内容在“上下标与间距”页面中有详细说明,包括机制以及与 \hphantom 的区别。这里要记住的是:\smash(把高的降下来)与 \vphantom / \mathstrut(把低的抬上去)是对齐高度的一对互补工具

\phantom — 用不可见占位来对齐

问题。 在多行公式中,有时希望下行的某一项正好位于上行某一项的正下方,但左侧长度不同导致列对不齐。手动塞空格一旦字体或公式变化就会再次坏掉。

修正方法。 \phantom{...} 是一个不可见盒子,拥有与正常排版参数时相同的高度、深度和宽度。把要对齐的那个表达式原样传给 \phantom,就会得到与该表达式宽度完全相同的空白,列自然对齐。只需要横向宽度时,使用 \hphantom{...}(高度和深度为零)。

latex
% 「= 」の左を、上の行の項の幅だけ空けて桁をそろえる
\begin{align*}
  f(x) &= x^2 + 2x + 1 \\
  \phantom{f(x)} &= (x + 1)^2
\end{align*}

在这个例子中,第二行左侧的 \phantom{f(x)} 会预留一个与 f(x) 同宽的空白,因此两个 = 会纵向对齐。\phantom 家族(\hphantom\vphantom)的详细说明也在“上下标与间距”页面中。

\mathclap\mathrlap\mathllap — 零宽盒子(横向的 \smash

问题。 求和或乘积符号下方的条件有时比运算符本身更宽,例如 \sum_{1 \le i \le j \le n}。于是 LaTeX 会为了容纳这个宽度,在求和号两侧打开空白,使整个公式显得被拉长。在表格或对齐环境中,这段额外宽度还可能让整列偏移。

修正方法。 mathtools 的 \mathclap{...} 会把参数放入零宽盒子并居中(左右等量伸出)。条件仍然可见,但公式宽度保持为运算符本体的宽度。若只想向一侧伸出,使用向左贴出的 \mathllap{...} 或向右贴出的 \mathrlap{...}。事实上,它们就是作为 \smash 的横向对应物设计的:\smash 把纵向尺寸归零,而 lap 系列把横向尺寸(宽度)归零。

latex
% 問題:長い下付き条件が総和の前後に余白を作る
\[ \sum_{1 \le i \le j \le n} a_{ij} \]

% 直し方:条件を幅ゼロの箱に入れ、式の幅を記号本体に保つ
\[ \sum_{\mathclap{1 \le i \le j \le n}} a_{ij} \]

这里假定已经加载 mathtools(\usepackage{mathtools},它会自动加载 amsmath)。这些命令、正文模式的 \clap 等,以及 [mathstyle] 可选参数,在 mathtools 页面中有详细说明。

如果不想把条件“横向压缩”,而是想叠成多行,适合使用 amsmath 的 \substack{...}。例如写 \sum_{\substack{0<i<m \\ 0<j<n}},用 \\ 分行后,两个条件会在求和号下方排成两行。

叠放符号与收紧间距

问题(一)。 有时需要在现有符号的正上方或正下方放一个任意的小符号,例如用 \overset{!}{=} 在等号上方放感叹号表示“按要求相等”,或用 \overset{?}{=} 表示“真的相等吗?”。上下标(^_)会附在符号右侧,不会来到正上方或正下方。

修正方法。 使用 amsmath 的 \overset{above}{base}\underset{below}{base}\overset{!}{=} 会把小感叹号正放在等号上方。第二个参数是底座,第一个参数是添加的内容。

latex
\[
  a \overset{!}{=} b, \qquad x \overset{?}{=} y,
  \qquad A \overset{f}{\longrightarrow} B
\]

\overset / \underset 的更完整用法(应用到箭头、嵌套等)在“上下装饰”页面中说明。

问题(二)。 反过来,有时符号之间距离过大。典型例子是二重或三重积分:直接写 \int\int 时,两个积分号之间的间距太宽,看起来像彼此独立的积分。

修正方法。 用负细空白 \!(−3 mu,正好是 \, 的反向)把它们拉近。写成 \int\!\!\int 时,两个积分号会靠到合适距离(多重积分也可以使用 amsmath 提供的专用命令 \iint\iiint)。包含 \! 在内的数学间距微调命令,整理在“上下标与间距”页面的 mu 表中。

latex
\[
  \int\int f \, dA          % 間が空きすぎ
  \qquad
  \int\!\!\int f \, dA      % \! で適度に詰める
\]