请考虑以下示例:
\documentclass{article}
\usepackage{multido}
\usepackage[
round-mode = places,
round-precision = 4
]{siunitx}
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
\newcommand*\horse[1]{\calc{3.5*sin(pi/#1)}}
\begin{document}
\multido{\i=2+1}{5}{\num{\horse{\i}}\quad}
\end{document}
是否可以从数字中删除尾随的零?(在这种情况下,它意味着得到3.5
而不是3.5000
和 而1.75
不是1.7500
。)
更新
看来我无法实现我的愿望;因此这个问题应该结束吗?
答案1
您可以使用信特压裂。该包应该有一个本机变体\xintTrunc
或\xintRound
例程,可以删除尾随零,由于缺少它,我编写了一个快速破解程序。
最初的这个 hack 并不完全令人满意(整数处理不好)。下面有两种方法。
更新:第二种方法现在允许二可选参数,第一个是小数点后的位数(默认4
),第二个是小数点(默认.
)。这是可扩展。
\documentclass{article}
\usepackage{expl3}
\usepackage{multido}
% \usepackage[
% round-mode = places,
% round-precision = 4
% ]{siunitx}
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
\newcommand*\horse[1]{\calc{3.5*sin(pi/#1)}}
\newcommand*\horsenegative[1]{\calc{-3.5*sin(pi/#1)}}
\usepackage{xintfrac}
%///////////////////////////////////////////////////////////////////////
\makeatletter
% quickly written, there might be a simpler way
% you can modify \myNum@ to replace the dot by a comma if you prefer
% this method will work up to nine fixed point digits after decimal mark
% works also with negative numbers
% \def\myNum@ #1.{\the\numexpr #1.}% <- replace the last dot by the sep
% % you need
% \newcommand*{\myNum}[1]{\xintRev{\expandafter\expandafter\expandafter
% \myNum@\xintRev{\xintRound{4}{#1}}}}
%
%\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
% but this had problems: would not handle well the case of integers, and even
% crash on zero, (\xintRound then does not print 0.0000 but just 0 without a
% dot). Here are now two general methods:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% method allowing customizing on output of the decimal mark:
% (but needs some modifications to switch from 4 to another number of digits)
\newcommand*{\myNum}[1]{\expandafter\myNum@
\romannumeral0\xintround {4}{#1}0000\relax }
\def\myNum@ #1{\if#10\expandafter\myNum@zero\fi \myNum@@ #1}
\def\myNum@@ #1.#20000#3\relax{\ifx\relax#2\relax \expandafter\myNum@int\fi
#1,#2}% <- we use a comma as decimal mark
% as comma was used above, must also be used here:
\def\myNum@int #1,{#1}% <- case of an integral number (positive or negative)
\def\myNum@zero #1\relax{0}% <- case of zero
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% another way, easily generalized to any given number of digits,
% (actually, generalization already done: nb of digits is optional arg)
% \newcommand*{\myNumVar}[2][4]{\expandafter\expandafter\expandafter
% \myNumVar@\xintREZ{\xintRound {#1}{#2}}}
% \def\myNumVar@ #1/1[#2]%
% {\xintifSgn {#2}{\xintTrunc {-#2}{#1[#2]}}{#1}{\xintNum{#1[#2]}}}
% now allows arbitrary separator as second optional argument:
% **** and is expandable! ****
\catcode`_ 11
\def\myNumVar #1{\myNumVar_chkopta #1\Z }
\def\myNumVar_chkopta #1{\ifx [#1\expandafter\myNumVar_opta
\else\expandafter\myNumVar_noopta
\fi #1}
\def\myNumVar_noopta #1\Z {\expandafter\expandafter\expandafter
\myNumVar@\xintREZ{\xintRound {4}{#1}}.}
\def\myNumVar_opta [\Z #1]#2{\myNumVar_chkoptb #2\Z {#1}}
\def\myNumVar_chkoptb #1{\ifx [#1\expandafter\myNumVar_optb
\else\expandafter\myNumVar_nooptb
\fi #1}
\def\myNumVar_optb [\Z #1#2]#3{\expandafter\expandafter\expandafter
\myNumVar@\xintREZ{\xintRound {#1}{#3}}{#2}}
\def\myNumVar_nooptb #1\Z #2{\expandafter\expandafter\expandafter
\myNumVar@\xintREZ{\xintRound {#2}{#1}}.}
\catcode`_ 8
\def\myNumVar@ #1/1[#2]#3%
{\xintifSgn {#2}{\expandafter\expandafter\expandafter
\myNumVar@@ \xintTrunc {-#2}{#1[#2]}.{#3}}%
{#1}%
{\xintNum{#1[#2]}}}
\def\myNumVar@@ #1.#2.#3{#1#3#2}
\makeatother
\begin{document}
\verb|\myNum| uses a comma on output:
\multido{\i=2+1}{5}{\myNum{\horse{\i}}\quad}
\multido{\i=2+1}{5}{\myNum{\horsenegative{\i}}\quad}
\verb|\myNumVar| has an optional argument to specify the number of digits
(possibly zero) after the dot as decimal mark:
\multido{\i=2+1}{5}{\myNumVar [12]{\horse{\i}}\quad}
\multido{\i=2+1}{5}{\myNumVar [12]{\horsenegative{\i}}\quad}
\multido{\i=2+1}{5}{\myNumVar [0]{\horse{\i}}\quad}
\multido{\i=2+1}{5}{\myNumVar [0]{\horsenegative{\i}}\quad}
\verb|\myNumVar| has a \textbf{second} optional argument to specify the
separator:
\multido{\i=2+1}{5}{\myNumVar [12][,]{\horse{\i}}\quad}
\multido{\i=2+1}{5}{\myNumVar [12][,]{\horsenegative{\i}}\quad}
If you want to use crazy things like [ itself as separator you can do it:
\verb|\myNumVar [12][[]{stuff}|
\multido{\i=2+1}{5}{\myNumVar [12][[]{\horse{\i}}\quad}
But with ], use braces
\verb|\myNumVar [12][{]}]{stuff}|
\multido{\i=2+1}{5}{\myNumVar [12][{]}]{\horse{\i}}\quad}
Integral numbers do not have a decimal mark:
\myNum {-3.0000}=\myNumVar [5]{-3.0000}
\myNum {0.0000}=\myNumVar [13][!]{0.0000}
\myNum {-300.0000}=\myNumVar [7][;]{-300.0000}
\verb|\myNumVar| is expandable:\edef\test {\myNumVar [17][;]{1/1250}}
\verb|\edef\test {\myNumVar [17][;]{1/1250}}\meaning\test|
\texttt{\meaning\test}
\end{document}
答案2
自从3.0版从 2021 年开始,有一个选项round-pad
似乎可以满足您的要求:
\documentclass{article}
\usepackage{multido}
\usepackage[
round-mode = places,
round-precision = 4,
round-pad = false %% true by default
]{siunitx}
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
\newcommand*\horse[1]{\calc{3.5*sin(pi/#1)}}
\begin{document}
\multido{\i=2+1}{5}{\num{\horse{\i}}\quad}
\end{document}
输出:
答案3
推荐使用包的解决方案fp
。
\documentclass[preview,border=12pt,12pt]{standalone}
\usepackage[nomessages]{fp}
\usepackage{multido}
\newcommand*\horse[1]{\FPeval\calc{clip(trunc(3.5*sin(pi/#1):6))}\calc}
\begin{document}
\multido{\i=2+1}{5}{\horse{\i}\quad}
\end{document}
答案4
你问,
是否可以删除数字后面的零?
使用 LuaLaTeX 非常简单 —— 不需要siunitx
包及其\num
宏。:-)
\documentclass{article}
\usepackage{luacode} % for '\luaexec' macro
% Create 2 Lua functions, 'horse' and 'mynum':
\luaexec{
function horse ( i )
return ( 3.5 * math.sin ( math.pi / i ) )
end
function mynum ( j )
return ( string.format ( '\%.5g' , j ) )
end
}
% Create a LaTeX wrapper macro for 'mynum' function:
\newcommand\mynum[1]{\directlua{tex.sprint(mynum(#1))}}
\begin{document}
\mynum{1.750000001}
\directlua { for i=2,6 do
tex.sprint ( mynum ( horse ( i ) ) .. '\\quad' )
end
}
\end{document}