以 mm 表示的各种单位 (ex、em、in、pt、bp、dd、pc) 是什么?

以 mm 表示的各种单位 (ex、em、in、pt、bp、dd、pc) 是什么?

如何确定中不同单位(测量1ex1em1in1pt1bp1dd)的长度?1pcmm

答案1

以下是 Herbert 答案的一个变体,使用\dimexpr(灵感来自主题\ifnum 表示实数\convertto{mm}{1pt}comp.text.tex 的转换),它允许以纯粹可扩展的方式进行转换。语法1pt如下mm

\makeatletter
\def\convertto#1#2{\strip@pt\dimexpr #2*65536/\number\dimexpr 1#1}
\makeatother

结果与打印长度包,可能是因为其\dimexpr执行的算术与 TeX 略有不同。下面是显示所有转换长度的表格(我省略了sp以避免算术溢出):

\documentclass[a4paper]{article}

\usepackage{array}
\usepackage[hmargin=2cm]{geometry}

\makeatletter
%http://groups.google.com/group/comp.text.tex/msg/7e812e5d6e67fcc5
\def\convertto#1#2{\strip@pt\dimexpr #2*65536/\number\dimexpr 1#1}
\makeatother

\begin{document}

\begin{center}\begin{tabular}
  {>{\def\colunit{pt}}l<{\convertto{\rowunit}{1\colunit}}
   >{\def\colunit{mm}}l<{\convertto{\rowunit}{1\colunit}}
   >{\def\colunit{cm}}l<{\convertto{\rowunit}{1\colunit}}
   >{\def\colunit{ex}}l<{\convertto{\rowunit}{1\colunit}}
   >{\def\colunit{em}}l<{\convertto{\rowunit}{1\colunit}}
   >{\def\colunit{bp}}l<{\convertto{\rowunit}{1\colunit}}
   >{\def\colunit{dd}}l<{\convertto{\rowunit}{1\colunit}}
   >{\def\colunit{pc}}l<{\convertto{\rowunit}{1\colunit}}
   >{\def\colunit{in}}l<{\convertto{\rowunit}{1\colunit}}
   >{\bfseries}l}
\multicolumn{1}{l}{\bfseries 1pt} & \multicolumn{1}{l}{\bfseries 1mm} & \multicolumn{1}{l}{\bfseries 1cm} & \multicolumn{1}{l}{\bfseries 1ex} & \multicolumn{1}{l}{\bfseries 1em} & \multicolumn{1}{l}{\bfseries 1bp} & \multicolumn{1}{l}{\bfseries 1dd} & \multicolumn{1}{l}{\bfseries 1pc} & \multicolumn{1}{l}{\bfseries 1in} & \\
\gdef\rowunit{pt} & & & & & & & & & \rowunit\\
\gdef\rowunit{mm} & & & & & & & & & \rowunit\\
\gdef\rowunit{cm} & & & & & & & & & \rowunit\\
\gdef\rowunit{ex} & & & & & & & & & \rowunit\\
\gdef\rowunit{em} & & & & & & & & & \rowunit\\
\gdef\rowunit{bp} & & & & & & & & & \rowunit\\
\gdef\rowunit{dd} & & & & & & & & & \rowunit\\
\gdef\rowunit{pc} & & & & & & & & & \rowunit\\
\gdef\rowunit{in} & & & & & & & & & \rowunit\\
\end{tabular}\end{center}

\end{document}

答案2

开始 (2017)

TeX 输入以特定单位表示的尺寸的精确规则在这两篇文章中有评论:

根本原因是,内部所有维度都是单位的整数倍sp,因此必须进行一些转换。以下是一些要点:

  • 从规范中获取的内部维度集cm与从以 为单位的维度中获取的内部维度集具有非空对称差异in。如果打算使用\ifdim测试,这一点很重要。这是核心 TeX 方面,不会被任何用于测试维度相等性的更高级别接口更改。

  • 当用给定单位表示维度时<unit>,粒度为1/65536<unit>,使用小数点后超过五位数字只能带来一次性变化。但很难猜测边界:超过 17 位小数就不会有什么变化,但从 17 位小数获得的结果不一定与从四舍五入这 17 位小数变为只有 5 位小数。这可能会让人感到惊讶,我在这里提供了一些您可以尝试的示例:

    • 0.22222pt(来自 2/9)给出 14563sp 但 0.22222222222222222pt 给出 14564sp。必须使用 0.22223pt 才能获得 14654sp。

    • 1.53333pt(来自 23/15)给出 100488sp 但 1.533333333333333333pt 给出 100489sp。必须使用 1.53334pt 才能获得 100489sp。

    是的,使用 0.66667pt 是正确的选择,但这有点偶然,正如上面的两个例子所示:有时应该朝相反的方向舍入才能得到 17 位数字的完整规范所给出的结果。(不幸的是,我似乎丢失了一个测试过这些内容的文件,但我记得我的测试表明,在大约的10%测试案例中需要反直觉的舍入,使用像上面那样的小分数构建)。

维度单位越大,内部表示越不精确。因此,使用in是一种精度低于使用的输入方法,而cm使用 的精度又低于使用pt。例如,使用em通常意味着您有一个10sp粒度,并且即使在使用 单位的维度表达式中使用 17 位小数,也无法低于该粒度em。使用pt可确保最小1sp粒度。

关于 Didot 点,在信特手动的。

(2017年底添加内容)


这是另一种类型的表格。它给出了单位之间的精确的不可约换算因子(emex是特殊的字体相关情况;对于它们我使用\dimexpr但这似乎不是一个好主意,也许最好从合适的参数中获取它们\fontdimen)。

在精确的表格之后,我还给出了一个将数值四舍五入到小数点后五位的表格。

更新:根据评论中的建议,首先是表格。 似乎有些可疑em:它似乎完全正确10pt+1sp,而不是更直观合理的10pt。我猜想10pt在这种情况下,使用默认的 CM 字体应该完全正确。但我刚刚用 进行了测试\the\fontdimen6\font,它也让我感到惊讶10.00002pt,(用 pdftex 编译)。

更新:在关闭互联网一段时间之前,我检查了em粗体、倾斜和电传打字机:分别是11.5pt-4sp10pt+1sp10.5pt-7sp也许一些字体专家可以解释一下这种机制是什么?也许是在字体创建过程的某个阶段从大点进行的底层转换?

更新:我对连分数进行了一些研究, 的一个很好的近似值1dd是,107/100pt这从第二个表中的小数展开式中也可以清楚地看出,而 (以1dd毫米为单位)的 的一个非常好的分数近似值是44/117(先前的中心收敛是,与中的3/8=0.375精确值相比已经相当不错了)。0.3760650274...1ddmm

精确换算表

四舍五入至 5 位

\documentclass{article}

\usepackage{xintfrac} 
% http://www.ctan.org/tex-archive/macros/generic/xint
% This code was compiled with the version 1.06a of the xint
% bundle dated 2013/05/09, which should appear soon on CTAN.
% The current CTAN version 1.06 should be also OK for this.

\usepackage{array}
\usepackage[hmargin=.5cm]{geometry}

% Conversions to the basic dimension, chosen to be the centimeter
% Base dimension: 1cm
\def\onecm {1}
\def\onemm {1/10}
\def\onein {2.54}
%% \def\onept {\xintMul {1/72.27}{\onein}}
%% simpler:
\def\onept {2.54/72.27}
%% \def\onebp {\xintMul {1/72}{\onein}}
%% simpler:
\def\onebp {2.54/72}
\def\onepc {\xintMul {12}{\onept}}
\def\oneex {\xintMul {\the\numexpr\dimexpr 1ex\relax\relax}{\onesp}}
\def\oneem {\xintMul {\the\numexpr\dimexpr 1em\relax\relax}{\onesp}} 
\def\onedd {\xintMul {1238/1157}{\onept}} 
% 1157 dd = 1238 pt I take this conversion factor from the TeXBook 
% Wikipedia has other conversion factors, but of course here we
% have to do it the TeX way.
\def\onecc {\xintMul {12}{\onedd}}
\def\onesp {\xintMul {1/65536}{\onept}}


% Routines with delimited arguments, the good old TeX way
% (completely expandable)
\makeatletter

% exact conversion to an irreducible fraction:
% example: \convertexactly 126.2772pt\to {bp}
% and `pt' may be a macro expanding to it.
% idem for {bp} which may be a macro expanding to bp
\def\convertexactly #1\to #2%
    {\xintIrr{\convertexactly@ #1\to {#2}}}%

% Variant with rounding at a number of decimal places
% given by first argument.
\def\convertwithrounding #1#2\to #3%
    {\xintRound {#1}{\convertexactly@ #2\to {#3}}}%

% routines doing the job:

\def\convertexactly@ #1\to
{%
    \romannumeral0%
    \expandafter\expandafter\expandafter
    \convertexactly@a
    \xintReverseOrder {#1}\Z
}%
\def\convertexactly@a #1%
{%
    \ifcat\noexpand #1\relax
       \expandafter \convertexactly@b
    \else
       \expandafter \convertexactly@c
    \fi #1%
}%
\def\convertexactly@b #1#2\Z #3%
{%
    \xintdiv {\xintMul {\xintReverseOrder{#2}}{\csname one#1\endcsname}}
             {\csname one#3\endcsname}%
}%
\def\convertexactly@c #1#2#3\Z #4%
{%
    \xintdiv {\xintMul {\xintReverseOrder{#3}}{\csname one#2#1\endcsname}}
             {\csname one#4\endcsname}%
}%

\makeatother

\def\bigstrut {\vbox to 24pt{}\vbox to 12pt{}}%

\begin{document}

Testing:

72.27pt is exactly \convertexactly 72.27pt\to {bp}bp

1/2.54in is exactly \convertexactly 1/2.54in\to {mm}mm

10pt is exactly (for this font) \convertexactly 10pt\to {ex}ex, 
or approximately \convertwithrounding{20}10pt\to {ex}ex

10pt is exactly (for this font) \convertexactly 10pt\to {em}em, 
or approximately \convertwithrounding{20}10pt\to {em}em

1em is exactly (for this font) \convertexactly
1em\to {pt}pt, or approximately
\convertwithrounding{20}1em\to {pt}pt. 

And indeed
\verb+\the\dimexpr 1em\relax+ gives \the\dimexpr 1em\relax{} and
\verb+\the\fontdimen6\font+ gives \the\fontdimen6\font

1ex is exactly (for this font) \convertexactly 1ex\to {pt}pt, or approximately
\convertwithrounding{20}1ex\to {pt}pt. 

And indeed
\verb+\the\dimexpr 1ex\relax+ gives \the\dimexpr 1ex\relax.

\def\tableentry{$\displaystyle\xintFrac{\convertexactly 1\colunit\to\rowunit}$\bigstrut}

\begin{center}\begin{tabular}
  {>{\def\colunit{pt}}l<{\tableentry}
   >{\def\colunit{mm}}l<{\tableentry}
   >{\def\colunit{cm}}l<{\tableentry}
   >{\def\colunit{ex}}l<{\tableentry}
   >{\def\colunit{em}}l<{\tableentry}
   >{\def\colunit{bp}}l<{\tableentry}
   >{\def\colunit{dd}}l<{\tableentry}
   >{\def\colunit{pc}}l<{\tableentry}
   >{\def\colunit{in}}l<{\tableentry}
   >{\bfseries}l}
\multicolumn{1}{l}{\bfseries 1pt} & \multicolumn{1}{l}{\bfseries 1mm} &
\multicolumn{1}{l}{\bfseries 1cm} & \multicolumn{1}{l}{\bfseries 1ex} &
\multicolumn{1}{l}{\bfseries 1em} & \multicolumn{1}{l}{\bfseries 1bp} &
\multicolumn{1}{l}{\bfseries 1dd} & \multicolumn{1}{l}{\bfseries 1pc} &
\multicolumn{1}{l}{\bfseries 1in} & \\
\gdef\rowunit{pt} & & & & & & & & & \rowunit\\
\gdef\rowunit{mm} & & & & & & & & & \rowunit\\
\gdef\rowunit{cm} & & & & & & & & & \rowunit\\
\gdef\rowunit{ex} & & & & & & & & & \rowunit\\
\gdef\rowunit{em} & & & & & & & & & \rowunit\\
\gdef\rowunit{bp} & & & & & & & & & \rowunit\\
\gdef\rowunit{dd} & & & & & & & & & \rowunit\\
\gdef\rowunit{pc} & & & & & & & & & \rowunit\\
\gdef\rowunit{in} & & & & & & & & & \rowunit\\
\end{tabular}\end{center}

\clearpage

\def\tableentry{\convertwithrounding {5}1\colunit\to\rowunit}

\begin{center}\begin{tabular}
  {>{\def\colunit{pt}}l<{\tableentry}
   >{\def\colunit{mm}}l<{\tableentry}
   >{\def\colunit{cm}}l<{\tableentry}
   >{\def\colunit{ex}}l<{\tableentry}
   >{\def\colunit{em}}l<{\tableentry}
   >{\def\colunit{bp}}l<{\tableentry}
   >{\def\colunit{dd}}l<{\tableentry}
   >{\def\colunit{pc}}l<{\tableentry}
   >{\def\colunit{in}}l<{\tableentry}
   >{\bfseries}l}
\multicolumn{1}{l}{\bfseries 1pt} & \multicolumn{1}{l}{\bfseries 1mm} &
\multicolumn{1}{l}{\bfseries 1cm} & \multicolumn{1}{l}{\bfseries 1ex} &
\multicolumn{1}{l}{\bfseries 1em} & \multicolumn{1}{l}{\bfseries 1bp} &
\multicolumn{1}{l}{\bfseries 1dd} & \multicolumn{1}{l}{\bfseries 1pc} &
\multicolumn{1}{l}{\bfseries 1in} & \\
\gdef\rowunit{pt} & & & & & & & & & \rowunit\\
\gdef\rowunit{mm} & & & & & & & & & \rowunit\\
\gdef\rowunit{cm} & & & & & & & & & \rowunit\\
\gdef\rowunit{ex} & & & & & & & & & \rowunit\\
\gdef\rowunit{em} & & & & & & & & & \rowunit\\
\gdef\rowunit{bp} & & & & & & & & & \rowunit\\
\gdef\rowunit{dd} & & & & & & & & & \rowunit\\
\gdef\rowunit{pc} & & & & & & & & & \rowunit\\
\gdef\rowunit{in} & & & & & & & & & \rowunit\\
\end{tabular}\end{center}

\end{document}

测试转换宏

事实上近似值20,小数点后有1 位,对于1em1ex,是精确的,分母是 2 的幂,完整的十进制展开式中只有显示的后面有零。我仍然不太明白为什么在 CM 字体的情况下1em结果是655361sp而不是。这很奇怪。655360sp=10pt10pt+1sp

答案3

替代文本

并且可以看到 TeX 的优秀算法.. ;-)

\documentclass{article}
\usepackage{printlen}
\parindent=0pt

\newlength\Length \Length=1cm
\begin{document}

\tabular{p{2cm}p{2cm}}
\mbox{--- 1cm ---}

\uselengthunit{cm}\printlength{\Length}\
\uselengthunit{mm}\printlength{\Length}\
\uselengthunit{in}\printlength{\Length}\
\uselengthunit{pt}\printlength{\Length}\
\uselengthunit{bp}\printlength{\Length}\
\uselengthunit{sp}\printlength{\Length}\
\uselengthunit{pc}\printlength{\Length}\
& 
\mbox{--- 1em ---}
\Length=1em
\uselengthunit{cm}\printlength{\Length}\
\uselengthunit{mm}\printlength{\Length}\
\uselengthunit{in}\printlength{\Length}\
\uselengthunit{pt}\printlength{\Length}\
\uselengthunit{bp}\printlength{\Length}\
\uselengthunit{sp}\printlength{\Length}\
\uselengthunit{pc}\printlength{\Length}
\endtabular
\end{document}

答案4

与 Philippe Goutet 的相同,但使用fpLaTeX3 模块;然而命令的语法\convertto不同:

\convertto{1in}{pt}

返回72.26999,仅数字。使用 ,\convertto*{1in}{pt}我们将获得72.26999pt,带单位。

\documentclass[a4paper]{article}

\usepackage{array}
\usepackage[hmargin=2cm]{geometry}

\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\convertto}{smm}
 {
  \egreg_convertto:nn {#2}{#3}
  \IfBooleanT{#1}{#2}
 }

\cs_new:Npn \egreg_convertto:nn #1 #2
 {
  \fp_eval:n { round( \dim_to_decimal:n { #1 } / \dim_to_decimal:n {1#2} , 5 ) }
 }
\ExplSyntaxOff

\begin{document}

\begin{center}\begin{tabular}
  {>{\def\colunit{pt}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{mm}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{cm}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{ex}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{em}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{bp}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{dd}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{pc}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{in}}l<{\convertto{1\colunit}{\rowunit}}
   >{\bfseries}l}
\multicolumn{1}{l}{\bfseries 1pt} & \multicolumn{1}{l}{\bfseries 1mm} &
\multicolumn{1}{l}{\bfseries 1cm} & \multicolumn{1}{l}{\bfseries 1ex} &
\multicolumn{1}{l}{\bfseries 1em} & \multicolumn{1}{l}{\bfseries 1bp} &
\multicolumn{1}{l}{\bfseries 1dd} & \multicolumn{1}{l}{\bfseries 1pc} &
\multicolumn{1}{l}{\bfseries 1in} & \\
\gdef\rowunit{pt} & & & & & & & & & \rowunit\\
\gdef\rowunit{mm} & & & & & & & & & \rowunit\\
\gdef\rowunit{cm} & & & & & & & & & \rowunit\\
\gdef\rowunit{ex} & & & & & & & & & \rowunit\\
\gdef\rowunit{em} & & & & & & & & & \rowunit\\
\gdef\rowunit{bp} & & & & & & & & & \rowunit\\
\gdef\rowunit{dd} & & & & & & & & & \rowunit\\
\gdef\rowunit{pc} & & & & & & & & & \rowunit\\
\gdef\rowunit{in} & & & & & & & & & \rowunit\\
\end{tabular}\end{center}

\end{document}

\convertto和均可\convertto*在可扩展的上下文中使用。

在此处输入图片描述

同一张表,但siunitx(与已建的表进行比较)。需要事先准备好表的主体。

\documentclass[a4paper]{article}

\usepackage{siunitx,array}
\usepackage[hmargin=1cm]{geometry}
\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \g_egreg_convertto_units_seq
\seq_new:N \l_egreg_convertto_temp_seq
\tl_new:N \l_egreg_convertto_body_tl

\seq_gset_from_clist:Nn \g_egreg_convertto_units_seq
 {
  pt, mm, cm, ex, em,  bp, dd, pc, in
 }

\cs_new_protected:Nn \__egreg_convertto_maketable:
 {
  \seq_map_inline:Nn \g_egreg_convertto_units_seq
   {
    \seq_clear:N \l_egreg_convertto_temp_seq
    \seq_map_inline:Nn \g_egreg_convertto_units_seq
     {
      \seq_put_right:Nx \l_egreg_convertto_temp_seq { \egreg_convertto:nn { 1####1 } { ##1 } }
     }
    \tl_put_right:Nx \l_egreg_convertto_body_tl
     {
      \seq_use:Nn \l_egreg_convertto_temp_seq { & } & \exp_not:n { \textbf{##1} \\ }
     }
   }
  \seq_set_map:NNn \l_egreg_convertto_temp_seq \g_egreg_convertto_units_seq { {\exp_not:N \textbf{1\,##1}} }
 }

\NewDocumentCommand{\maketable}{}
 {
  \__egreg_convertto_maketable:
  \begin{tabular}{*{\seq_count:N \g_egreg_convertto_units_seq}{S[table-format=2.5]}l}
  \seq_use:Nn \l_egreg_convertto_temp_seq { & } \\
  \l_egreg_convertto_body_tl
  \end{tabular}
 }

\NewExpandableDocumentCommand{\convertto}{smm}
 {
  \egreg_convertto:nn {#2}{#3}
  \IfBooleanT{#1}{#2}
 }

\cs_new:Npn \egreg_convertto:nn #1 #2
 {
  \fp_eval:n { round( \dim_to_decimal:n { #1 } / \dim_to_decimal:n {1#2} , 5 ) }
 }
\ExplSyntaxOff

\begin{document}

\begin{center}
\sisetup{group-digits=false}
\maketable
\end{center}

\begin{center}
\begin{tabular}
  {>{\def\colunit{pt}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{mm}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{cm}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{ex}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{em}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{bp}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{dd}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{pc}}l<{\convertto{1\colunit}{\rowunit}}
   >{\def\colunit{in}}l<{\convertto{1\colunit}{\rowunit}}
   >{\bfseries}l}
\multicolumn{1}{l}{\bfseries 1pt} & \multicolumn{1}{l}{\bfseries 1mm} &
\multicolumn{1}{l}{\bfseries 1cm} & \multicolumn{1}{l}{\bfseries 1ex} &
\multicolumn{1}{l}{\bfseries 1em} & \multicolumn{1}{l}{\bfseries 1bp} &
\multicolumn{1}{l}{\bfseries 1dd} & \multicolumn{1}{l}{\bfseries 1pc} &
\multicolumn{1}{l}{\bfseries 1in} & \\
\gdef\rowunit{pt} & & & & & & & & & \rowunit\\
\gdef\rowunit{mm} & & & & & & & & & \rowunit\\
\gdef\rowunit{cm} & & & & & & & & & \rowunit\\
\gdef\rowunit{ex} & & & & & & & & & \rowunit\\
\gdef\rowunit{em} & & & & & & & & & \rowunit\\
\gdef\rowunit{bp} & & & & & & & & & \rowunit\\
\gdef\rowunit{dd} & & & & & & & & & \rowunit\\
\gdef\rowunit{pc} & & & & & & & & & \rowunit\\
\gdef\rowunit{in} & & & & & & & & & \rowunit\\
\end{tabular}\end{center}

\end{document}

在此处输入图片描述

相关内容