优点和缺点:pgfmath 的数学表达式与 l3fp 的浮点表达式

优点和缺点:pgfmath 的数学表达式与 l3fp 的浮点表达式

如果在为环境编写代码时首先需要随机生成器tikzpicture,就像我的情况一样,那么很自然地会在 的第 89 节中寻找配方Tantau's TikZ Manual。从昨天开始,我就可以开始使用expl3 L3fp's randrandint函数 - 迟做总比不做好!,我有理由重写我的小工具箱,其中包含少量的document commands和相关的,cs_ functions以替换pgfmathl3fp。经过一些调整后,该工具箱可以完成以前所做的所有事情,而且做得更好,如下面的 MWE 中所述。

我的问题如下:pgfmath我的工具箱中的 -variant 可能有什么用处?在哪些情况下只pgfmath需要 就够了?当前的问题是randrandintrandom (0, 1, or 2 arguments)以及相关的设置方法。然而,问题的更广泛范围涉及和中常见的seed values许多其他函数的使用。floating point expressionsl3fpmathematical expressionpgfmath

\documentclass{article}
% RN. 9 April 2017
% BRIEF DESCRIPTION:
%    1. \myRandomNumberLThreeFP uses rand() and randint() provided by Expl3's
%       L3fp package. 
%    2. \myRandomNumberPGFMATH uses the random function provided by pgfmath. 
%    ADVANTAGES of expl3 fp over pgfmath are:
%    - Familiar syntax: for example ...
%      (1)  Allows the use of the familiar \int/fp_set/gset:Nn ... syntax to save 
%           a value to a variable, in place of the awkward 
%           \pgfmathsetmacro{<variable>}{random()}, etc.
%      (2)  pgfmath does not allow grouping in \cs_ functions - how then do I control 
%           local vs. global scope issues for the other variables resident in the 
%           same function?,  
%      (3)  ignores the check-declarations argument: \l_rn_randomInteger_int and 
%           \l_rn_randomInteger_fp are nowhere declared,
%      (4)  flags compile ERROR if \int_use:N or \fp_use:N is used when printing 
%           variables;
%    - Accuracy:
%      (1)  integers range -(10e16-1) to +(10e16-1) = 9,999,999,999,999,999 as 
%           opposed to (2e31-1) = 2,147,483,647 for pgfmath. 
%           NOTE: why then the "Number too big" error which persists even with all 
%           references to pgfmath removed?, 
%      (2)  reals have 16 decimal digits as opposed to 5 decimal digits for pgfmath.
%=======================
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
\usepackage{pgfmath}
%-----------------------
\ExplSyntaxOn

\int_new:N \g_rn_randomInteger_int

%\NewDocumentCommand\myRandomNumberLThreeFP{O{1}O{9999999999999999}}  %  "Number too big" error ?
\NewDocumentCommand\myRandomNumberLThreeFP{O{1}O{2147483647}}
  {
    \rn_randomInt_LThreePFG:nn {#1}{#2}
    randint:~\int_use:N \g_rn_randomInteger_int ,~
    rand():~\fp_eval:n {rand()} \\
  }

\cs_new:Npn \rn_randomInt_LThreePFG:nn #1#2
  {
\group_begin:
    \int_gset:Nn \g_rn_randomInteger_int {\fp_eval:n {randint(#1,#2)}} 
\group_end:
  }    

\NewDocumentCommand\myRandomNumberPGFMATH{O{1}O{2147483647}}
  {
%\group_begin:
    \rn_randomInt_PGFMATH:nn {#1}{#2}
    random:~\l_rn_randomInteger_int,~
    \pgfmathsetmacro{\l_rn_randomFloatingPoint_fp}{random()}
    random():~\l_rn_randomFloatingPoint_fp \\
%\group_end:
  }

\cs_new:Npn \rn_randomInt_PGFMATH:nn #1#2
  {
%\group_begin:
    \pgfmathsetmacro{\l_rn_randomInteger_int}{random(#1,#2)}  
%\group_end:
  }    

\ExplSyntaxOff
%-----------------------
\begin{document}
    1.~Expl3~L3fp Package:\\
  \myRandomNumberLThreeFP 
  \myRandomNumberLThreeFP 
  \myRandomNumberLThreeFP 

    2.~pgfmath:\\
  \myRandomNumberPGFMATH
  \myRandomNumberPGFMATH
  \myRandomNumberPGFMATH
\end{document}

答案1

这两个系统的设计目标有一些不同,这些不同可能是优点也可能是缺点,这取决于您的要求。该pgfmath引擎不可扩展,只需要经典的 TeX 基元。另一方面,它l3fp通过扩展工作,需要 LaTeX3 要求的扩展基元集:e-TeX 和\pdfstrcmp/或等效项(另见下文)。

主要考虑因素包括

  • pgfmath使用 TeX dimen 寄存器进行计算。这限制了精度,意味着没有内部值可以超过 ±16383.99999。另一方面,在内部l3fp使用整数计算(\numexpr),但使用允许 16 位精度的算法(目标是符合 IEEE754)。当然,这里在速度方面存在权衡。(请注意,确实pgf允许根据所需工作的性质切换到更准确的 FPU。)
  • pgfmath使用赋值工作,而l3fp通过纯扩展工作。可扩展计算在 TeX“需要数字”但确实意味着某些操作无法进行的上下文中很有用。特别是,pgfmath将允许将框设置操作放置在里面一个表达式,而l3fp只有先前设置的框的测量才是允许的。
  • 在 中实现的函数范围pgfmath比 中的大l3fp。例如,pgfmath涵盖了数组和双曲三角函数,而这两项目前在 中都不可用l3fp。(请参阅 中的“待办事项”列表interface3。)
  • 中的随机数l3fp需要引擎支持,而它们在 中直接实现pgfmath。目前,这意味着 XeTeX 中无法使用随机值(它缺少所需的原语),尽管这种情况在未来的某个阶段可能会改变。(可以在没有原语支持的情况下实现可扩展的随机值,但这会很慢,而且总体而言,努力和结果之间的平衡并不合理。)

相关内容