以下是 MWE,解释了我的意图。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\tikzmath{
\integer = 4/2; \decimal = 5/3;
\integerB=1/3*3;
}
$\integer$ is an integer, and it should be printed as 2.
And $\decimal$ is a decimal number, I would like to round it to 1.7.
Another difficulty is that $\integerB$ is an integer in fact,
and should be printed as 1.
\end{document}
我想知道是否可以测试一个数字以确定它是整数。或者,如果可以确定前两个小数是否足够接近 0 或 1,那就太好了。
答案1
\documentclass{article}
\usepackage{xintexpr}% recommended package
\newcommand\test[1]{\xintifboolexpr{ifint(#1, 1, 0)}
{\xinttheexpr reduce(#1)\relax\space (originally \texttt{\detokenize{#1}})
is an integer.}
{\xinttheiexpr[2] #1\relax\space (originally \texttt{\detokenize{#1}}),
we rounded to two decimal places) is not an integer.}\par
}
\begin{document}
\test{4/2}
\test{5/3}
\test{(1/3)*3}
\test{(1/7 - 1/8 - 1/57)*3192}
\test{(1/2 - 1/3 - 1/7 - 1/43 - 1/1807 - 1/3263443)*10650056950806}
\end{document}
答案2
从浮点表示中无法判断涉及除法或无理运算的算术运算的输出是否实际上是整数。
您可以考虑通过包提供l3fp
的模块。expl3
xfp
\documentclass{article}
\usepackage{xfp}
\begin{document}
$\fpeval{5/3}$ is a decimal number, I would like to round it to
$\fpeval{round(5/3,1)}$ or to $\fpeval{round(5/3,2)}$
Another difficulty is that $\fpeval{(1/3)*3}$ is an integer in fact,
and should be printed as $\fpeval{round((1/3)*3,1)}$ or
$\fpeval{round((1/3)*3,2)}$.
\end{document}
答案3
如果您的数字准确性很重要,您可以考虑将其交给计算机代数系统 (CAS)。该sagetex
软件包依赖于 CAS Sage;文档可以在 CTAN 上找到这里. Sage 上的文档这里.Sage 不是 LaTeX 发行版的一部分(它很大),因此需要安装在您的计算机上,或者更简单地通过免费可钙帐户。
\documentclass{article}
\usepackage{sagetex}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{sagesilent}
a = 4/2
b = 5/3
c = 1/3*3
\end{sagesilent}
$\sage{a}$ is an integer, and it should be printed as $\sage{a}$.
And $\sage{b}$ is not an integer. As a decimal it is approximately
$\sage{b.n(digits=6)}$. I would like to round it to $\sage{b.n(digits=1)}$.
Another difficulty is that $\sage{c}$ is an integer in fact,
and should be printed as $\sage{c}$.
\end{document}
请注意,Sage 会正确解释您的数字:4/2 被识别为 2,1/3*3 被识别为 1。它确实需要知道您想要的非整数格式;但它会识别出 5/3 是一个无法约简的分数,并将其保留为分数。要将其强制转换为小数并指定位数,我们附加 .n(digits=6);文档是这里。
答案4
这是一个基于 LuaLaTeX 的解决方案。\integer
(4/2) 和\integerB
((1/3)*3) 根据 Lua 规则自动计算为整数。 LaTeX 宏\round
接受两个参数,允许用户将数字四舍五入为小数点后指定的一组数字。
% !TEX TS-program = lualatex
\documentclass{article}
% Set up 2 auxilliary Lua functions to round numbers
\directlua{
function math.round_int ( x )
return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
end
function math.round ( x , n )
return ( math.round_int ( x*10^n ) / 10^n )
end
}
\newcommand\comp[1]{\directlua{tex.sprint(#1)}}
\newcommand\round[2]{\directlua{tex.sprint(math.round(#1,#2))}}
\newcommand{\integer}{\comp{4/2}}
\newcommand{\decimal}{\comp{5/3}}
\newcommand{\integerB}{\comp{(1/3)*3}}
\begin{document}
\integer\ is an integer.
\integerB\ is also an integer.
\decimal\ is a decimal number. I would like to round it to \round{\decimal}{1}.
\end{document}