使用 LaTeX3 格式化实数

使用 LaTeX3 格式化实数

我想格式化实数,这些实数是使用该包进行长时间计算的结果l3fp,以便将其作为值输出到 PDF 对象中的键。格式化的数字在“ ”后最多应有 9 位数字.,尾随零被修剪,并且没有指数部分。

\fp_round_places:Nn和的组合\fp_to_tl:N不会给出想要的结果,因为\fp_to_tl:N如果它更紧凑的话,有时会留下一个具有指数部分的实数。

\my_format_num:n|x{<real number>}因此,我自己编写了一个宏。它运行得很好,但我无法将结果保存到标记列表变量中。在这种情况下,我得到了 TeX 错误:

! Argument of \my_format_num:w has an extra }.

下面的代码是我目前所做的。我该如何改进它,以便将结果保存在 tl 变量中?

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \my_format_num:n|x{<real number without any exponent part>}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% macro to format real numbers
%
% * to show at most 9 places after `.'
% * trailing zeros removed
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cs_new:Nn\my_format_num:n{
  \exp_after:wN\my_format_num:w#1000000000\q_stop
}
\cs_generate_variant:Nn\my_format_num:n{x}

\cs_new:Npn\my_format_num:w#1.#2\q_stop{
  #1.\exp_after:wN\my_trim_places:w#2\q_stop
}
\cs_new:Npn\my_trim_places:w#1#2#3#4#5#6#7#8#9\q_stop{
  \my_trim_zeros:x{\exp_after:wN\tl_head:w#9\q_stop#8#7#6#5#4#3#2#1}
}
\cs_new:Nn\my_trim_zeros:n{
  \exp_after:wN\my_trim_zeros:w#1\q_stop
}
\cs_generate_variant:Nn\my_trim_zeros:n{x}
\cs_new:Npn\my_trim_zeros:w#1#2\q_stop{
  \str_if_eq:nnTF{#1}{0}{
    \int_compare:nNnTF{\tl_length:n{#2}}>{\c_one}{
      \exp_after:wN\my_trim_zeros:w#2\q_stop
    }{#2}
  }{
    \tl_reverse:n{#2}#1
  }
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
  \fp_set:Nn\my_vara_fp{-1.234e-8}
  \fp_set:Nn\my_varb_fp{123456789.987654321e-9}
  \fp_set:Nn\my_varc_fp{1.234}

  % result as expected: -0.000000012
  $\fp_use:N\my_vara_fp\rightarrow\my_format_num:x{\fp_use:N\my_vara_fp}$\par

  % result as expected: 0.123456789
  $\fp_use:N\my_varb_fp\rightarrow\my_format_num:x{\fp_use:N\my_varb_fp}$\par

  % result as expected: 1.234
  $\fp_use:N\my_varc_fp\rightarrow\my_format_num:x{\fp_use:N\my_varc_fp}$\par

%  cannot save result in tl var
%  \tl_set:Nx\my_vara_tl{\my_format_num:x{\fp_use:N\my_vara_fp}}
\end{document}
\ExplSyntaxOff

答案1

有了足够新的expl3(2012 年 7 月应该足够了),你可以做

\documentclass{article}
\usepackage{expl3, xparse}
\ExplSyntaxOn
\DeclareDocumentCommand { \myformat }{m}
  { \fp_to_decimal:n { round((#1),9) } }
\ExplSyntaxOff
\begin{document}
  \myformat{3.4}

  \myformat{1234.567891234567}

  \myformat{3+4-7+1.23456e-5}
\end{document}

答案2

感谢 Bruno 的评论,我已经想出了一个可行的解决方案。顶级宏的语法略有变化。尽管如此,在l3fpLaTeX3 包中添加具有类似 C 格式功能的函数将受到热烈欢迎!

\documentclass{article}
\usepackage{expl3}                          

\ExplSyntaxOn             
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \my_format_num:N<tl var>                  
% <tl var> contains a real number without exponent part
% the contents of <tl var> will be overwritten with the result
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% contents of <tl var> is formatted
% * to show at most 9 places after `.'
% * trailing zeros removed                                                 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cs_new:Nn\my_format_num:N{
  \tl_set:Nx#1{\exp_after:wN\my_format_num:w#1\q_stop}
}                             
\cs_new:Npn\my_format_num:w#1.#2\q_stop{
  #1.\exp_after:wN\my_trim_places:w#2000000000\q_stop
} 
\cs_new:Npn\my_trim_places:w#1#2#3#4#5#6#7#8#9\q_stop{
  \my_trim_zeros:f{\exp_after:wN\tl_head:w#9\q_stop#8#7#6#5#4#3#2#1}
}                                                                              
\cs_new:Nn\my_trim_zeros:n{
  \exp_after:wN\my_trim_zeros:w#1\q_stop
}
\cs_generate_variant:Nn\my_trim_zeros:n{f}
\cs_new:Npn\my_trim_zeros:w#1#2\q_stop{                          
  \str_if_eq:nnTF{#1}{0}{                                                      
    \int_compare:nNnTF{\tl_length:n{#2}}>{\c_one}{
      \exp_after:wN\my_trim_zeros:w#2\q_stop
    }{#2}                                                         
  }{                                                                                
    \tl_reverse:n{#2}#1                                     
  }                                 
}                                                                   
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%               

\begin{document}                       

  \fp_set:Nn\my_vara_fp{-1.234e-8}
  \fp_set:Nn\my_varb_fp{123456789.987654321e-9}
  \fp_set:Nn\my_varc_fp{1.234}                                                 

  \tl_set:Nx\my_vara_tl{\fp_use:N\my_vara_fp}
  \my_format_num:N\my_vara_tl

  \tl_set:Nx\my_varb_tl{\fp_use:N\my_varb_fp}
  \my_format_num:N\my_varb_tl

  \tl_set:Nx\my_varc_tl{\fp_use:N\my_varc_fp}               
  \my_format_num:N\my_varc_tl

  \my_vara_tl\par
  \my_varb_tl\par
  \my_varc_tl                                                                                                       

\end{document}

\ExplSyntaxOff

相关内容