是否有任何命令可以让我们提取像 2.36e6 这样的数字的尾数,以便我们可以得到 2.36?
像这样:
\mantissa{2.36e6}
答案1
您可以提取尾数和指数:
\documentclass{article}
\makeatletter
\newcommand{\mantissa}[1]{%
\hafid@mantissa#1ee\@nil
}
\def\hafid@mantissa#1e#2e#3\@nil{%
#1%
}
\newcommand{\exponent}[1]{%
\hafid@exponent#1ee\@nil
}
\def\hafid@exponent#1e#2e#3\@nil{%
#2%
}
\begin{document}
Mantissa: $\mantissa{1}$; Exponent: $\exponent{1}$\par
Mantissa: $\mantissa{1.2}$; Exponent: $\exponent{1.2}$\par
Mantissa: $\mantissa{1.2e3}$; Exponent: $\exponent{1.2e3}$\par
Mantissa: $\mantissa{1.2e-3}$; Exponent: $\exponent{1.2e-3}$\par
\end{document}
如果尾数或指数不存在,这些宏将不返回任何内容。如果指数未明确给出,则可以轻松修改以返回 0:只需将定义替换\hafid@exponent
为
\def\hafid@exponent#1e#2e#3\@nil{%
\ifx\relax#2\relax
0%
\else
#2%
\fi
}
该版本还允许符号输入(最终扩展为数字的控制序列;指数也可以输入为E
。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\mantissa}{m}
{
\hafid_mantissa:f { \tl_lower_case:n { #1 } }
}
\cs_new:Nn \hafid_mantissa:n
{
\__hafid_mantissa:www #1 ee \q_stop
}
\cs_generate_variant:Nn \hafid_mantissa:n { f }
\cs_new:Npn \__hafid_mantissa:www #1 e #2 e #3 \q_stop
{
#1
}
\DeclareExpandableDocumentCommand{\exponent}{m}
{
\hafid_exponent:f { \tl_lower_case:n { #1 } }
}
\cs_new:Nn \hafid_exponent:n
{
\__hafid_exponent:www #1 ee \q_stop
}
\cs_generate_variant:Nn \hafid_exponent:n { f }
\cs_new:Npn \__hafid_exponent:www #1 e #2 e #3 \q_stop
{
\tl_if_empty:nTF { #2 } { 0 } { #2 }
}
\ExplSyntaxOff
\begin{document}
Mantissa: $\mantissa{1}$; Exponent: $\exponent{1}$\par
Mantissa: $\mantissa{1.2}$; Exponent: $\exponent{1.2}$\par
Mantissa: $\mantissa{1.2e3}$; Exponent: $\exponent{1.2e3}$\par
Mantissa: $\mantissa{1.2e-3}$; Exponent: $\exponent{1.2e-3}$\par
Mantissa: $\mantissa{1.2E-3}$; Exponent: $\exponent{1.2E-3}$\par
\newcommand{\mynumber}{1.26e10}
Mantissa: $\mantissa{\mynumber}$; Exponent: \exponent{\mynumber}
\end{document}
注意:由于当前版本expl3
(2016/01/19 r6377 版本)存在缺陷,代码无法在 XeLaTeX 或 LuaLaTeX 下按预期工作。最简单的解决方法是不允许E
使用分隔符:
\DeclareExpandableDocumentCommand{\mantissa}{m}
{
\hafid_mantissa:f { #1 }
}
\DeclareExpandableDocumentCommand{\mantissa}{m}
{
\hafid_exponent:f { #1 }
}
答案2
您可以使用 TeX 参数文本匹配提取分量(尾数或指数):
\documentclass{article}
\makeatletter
\def\@mantissa#1e#2\relax{#1}
\def\@exponent#1e#2\relax{#2}
\newcommand{\mantissa}[1]{\expandafter\@mantissa#1\relax}
\newcommand{\exponent}[1]{\expandafter\@exponent#1\relax}
\makeatother
\begin{document}
\setlength{\parindent}{0pt}% Just for this example
\newcommand{\Value}{2.36e6}
Value: \Value
Mantissa: \mantissa{\Value}
Exponent: \exponent{\Value}
\end{document}
“非用户级”宏\@mantissa
和\@exponent
期望参数文本的形式<m>e<e>\relax
为e
\relax
必需的在输入流中。用户级宏\mantissa
和\exponent
都传递\relax
,但这意味着您只能传递使用科学计数法的数字/值,因此必须有符号<m>e<e>
。
答案3
只是为了多样性,这里有一个基于 LuaLaTeX 的解决方案。
以下代码设置了两个 Lua 函数,分别名为get_mant
和get_expo
,它们分别从诸如 之类的项中提取尾数和指数-1.23e+45
。该代码还提供了两个 TeX“包装器”宏,分别名为\GetMant
和\GetExpo
,它们调用 Lua 函数。因此,\GetMant{2.36e6}
返回2.36
,并\GetExpo{2.34e-56}
返回-56
。
假设\GetMant
和的输入\GetExpo
要么是用“科学”符号表示的有效数字,要么是求值为有效科学符号数字的宏。不过,代码不执行任何输入完整性检查:它假设您不会尝试从 或 等表达式中提取尾数和指数abcdefghi
。+55+e-66-d
主要的格式要求是输入字符串包含一个(且只有一个)字母e
;的实例E
也是可以的。
两条评论:
代码设置为
+
隐藏尾数和指数部分开头可能存在的任何符号。如果您确实想保留符号+
,只需删除tonumber
参数中的函数调用即可tex.sprint
。代码可以处理“空尾数”的情况,即,表达式如下
e22
:在这种情况下,尾数设置为1
。同样,代码还可以处理“空指数”的情况,即,表达式如下1.6e
:指数设置为0
。即使是极端(坦率地说有些荒谬)的空尾数/空指数情况,即e
或E
,也可以正确处理:尾数设置为1
,指数设置为0
。:-)
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{booktabs}
%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function get_mant ( s )
mant = string.gsub ( s, "^(.-)[eE](.-)$", "%1" )
if mant == "" then mant = "1" end
return tex.sprint ( tonumber(mant) )
end
function get_expo ( s )
expo = string.gsub ( s, "^(.-)[eE](.-)$", "%2" )
if expo == "" then expo = "0" end
return tex.sprint ( tonumber(expo) )
end
\end{luacode}
%% TeX-side code
\newcommand\GetMant[1]{\directlua{get_mant(\luastring{#1})}}
\newcommand\GetExpo[1]{\directlua{get_expo(\luastring{#1})}}
\begin{document}
\newcommand{\NumA}{-3.45e-678}
\newcommand{\NumB}{+1.23E+45}
\newcommand{\NumC}{e}
$\begin{array}{@{}lll@{}}
\mbox{Input} & \mbox{Mantissa} & \mbox{Exponent}\\
\midrule
\texttt{\NumA} & \GetMant{\NumA} & \GetExpo{\NumA}\\
\texttt{\NumB} & \GetMant{\NumB} & \GetExpo{\NumB}\\
\texttt{e22} & \GetMant{e22} & \GetExpo{e22} \\
\texttt{1.23E} & \GetMant{1.23E} & \GetExpo{1.23E}\\
\texttt{\NumC} & \GetMant{\NumC} & \GetExpo{\NumC}\\
\end{array}$
\end{document}