\num[round-mode=figures,round-precision=#2] 不是 \fp_eval:n 可以使用的数字

\num[round-mode=figures,round-precision=#2] 不是 \fp_eval:n 可以使用的数字

有时我想要/必须将计算分解为一系列步骤,因为我有一个想要在未来的计算中使用的术语,但由于有效数字很重要,所以我需要调整数字。

虽然不是最现实的,但我的 MWE 表明我使用expl3函数\fp_eval:n评估数学表达式的努力不能将siunitx舍入结果用作未来的输入。

示例:我们不使用完整的二次公式,而是将其分解为两个累积项来显示有效数字精度损失的影响:即,我们不在内存中一次评估整个表达式,而是将其分解为X1 = T1 + T2或,X2 = T1 - T2其中T1T2已经被评估并简化为说明性有效数字。

T1使用我的函数来求解和没有任何问题T2,但是使用T1T2来计算X1X2却会失败。

组合的fp_eval\num和分别用于求值、舍入和存储(用于继续使用)在下面的 MWE 中,但是,如果不生成我认为是错误的内容,newcommand我就无法成功调用第二轮命令。MyEvalnot a number

\documentclass[letter,12pt]{article}

\usepackage{expl3}

\usepackage{parskip}
\usepackage{setspace}

\usepackage{siunitx}
\usepackage{mathtools,amssymb}


%\ExplSyntaxOn
%   \cs_set_eq:NN \fpeval \fp_eval:n
%\ExplSyntaxOff

\ExplSyntaxOn
    \NewDocumentCommand {\MyEval} {m O{6} m}
    {
        \newcommand{#1}{
            \num[round-mode=figures,round-precision=#2]{\fp_eval:n {#3}}
        }
    }
\ExplSyntaxOff

\newcommand{\MySF}{6}

%\newcommand{\MyEval}[2]{%
%   \newcommand{#1}{%
%       \num[round-mode=figures,round-precision=4]{%
%           \fpeval{#2}%
%       }%
%   }%
%}%

\begin{document}\noindent   

\textbf{Quadratic Equation}: $x^2 + 40x + 2 = 0$ 

\renewcommand{\MySF}{4}

\newcommand{\qa}{1}
\newcommand{\qb}{40}
\newcommand{\qc}{2}

%\MyEval{\QuadraticxOne}[\MySF]{(1/2)*(1/\qa)*(-\qb + ((\qb)^2-(4*\qa*\qc))^(1/2))}
%\MyEval{\QuadraticxTwo}[\MySF]{(1/2)*(1/\qa)*(-\qb - ((\qb)^2-(4*\qa*\qc))^(1/2))}

\MyEval{\QuadratictOne}[\MySF]{(1/2)*(1/\qa)*(-\qb)}
\MyEval{\QuadratictTwo}[\MySF]{(1/2)*(1/\qa)*(((\qb)^2-(4*\qa*\qc))^(1/2))}

\MyEval{\QuadraticxOne}[\MySF]{\QuadratictOne+\QuadratictTwo}
\MyEval{\QuadraticxTwo}[\MySF]{\QuadratictOne-\QuadratictTwo}

    \begin{equation*}\begin{aligned}
        t_1 = \QuadratictOne\\
        t_2 = \QuadratictTwo\\
        %x_1 = \QuadraticxOne\\
        %x_2 = \QuadraticxTwo\\
    \end{aligned} \end{equation*}

\end{document}

答案1

\num是命令印刷数字,而不是操纵它们。浮点运算包括round

\documentclass{article}

\usepackage{xparse}

\usepackage{siunitx}
\usepackage{mathtools,amssymb}


\ExplSyntaxOn
\NewDocumentCommand {\MyEval} {m O{6} m}
 {
  \tl_new:N #1
  \tl_set:Nx #1 { \fp_eval:n { round( (#3) , #2 ) } }
 }
\ExplSyntaxOff

\newcommand{\MySF}{6}

\begin{document}

\textbf{Quadratic Equation}: $x^2 + 40x + 2 = 0$ 

\renewcommand{\MySF}{4}

\newcommand{\qa}{1}
\newcommand{\qb}{40}
\newcommand{\qc}{2}

\MyEval{\QuadratictOne}[\MySF]{(1/2)*(1/\qa)*(-\qb)}
\MyEval{\QuadratictTwo}[\MySF]{(1/2)*(1/\qa)*(((\qb)^2-(4*\qa*\qc))^(1/2))}

\MyEval{\QuadraticxOne}[\MySF]{\QuadratictOne+\QuadratictTwo}
\MyEval{\QuadraticxTwo}[\MySF]{\QuadratictOne-\QuadratictTwo}

\begin{align*}
t_1 &= \QuadratictOne\\
t_2 &= \QuadratictTwo\\
x_1 &= \QuadraticxOne\\
x_2 &= \QuadraticxTwo
\end{align*}

\end{document}

请注意,我\tl_set:Nx这样说是进行全面评估。

在此处输入图片描述

评论后有新版本

您需要将计算步骤与打印步骤分开。

\documentclass{article}

\usepackage{xparse}

\usepackage{siunitx}
\usepackage{mathtools,amssymb}

\ExplSyntaxOn
\NewDocumentCommand {\MyEval} {mm}
 {
  \tl_new:N #1
  \tl_set:Nx #1 { \fp_eval:n { #2 } }
 }
\NewDocumentCommand{\MyNum}{O{6}m}
 {
  \num[round-mode=figures,round-precision=#1]{#2}
 }
\ExplSyntaxOff

\newcommand{\MySF}{6}

\begin{document}

\textbf{Quadratic Equation}: $x^2 + 40x + 2 = 0$ 

\renewcommand{\MySF}{4}

\newcommand{\qa}{1}
\newcommand{\qb}{40}
\newcommand{\qc}{2}

\MyEval{\QuadratictOne}{(1/2)*(1/\qa)*(-\qb)}
\MyEval{\QuadratictTwo}{(1/2)*(1/\qa)*(((\qb)^2-(4*\qa*\qc))^(1/2))}

\MyEval{\QuadraticxOne}{\QuadratictOne+\QuadratictTwo}
\MyEval{\QuadraticxTwo}{\QuadratictOne-\QuadratictTwo}

\begin{align*}
t_1 &= \MyNum{\QuadratictOne}\\
t_2 &= \MyNum{\QuadratictTwo}\\
x_1 &= \MyNum[\MySF]{\QuadraticxOne}\\
x_2 &= \MyNum[\MySF]{\QuadraticxTwo}
\end{align*}

\end{document}

在此处输入图片描述

答案2

因此,siunitx我可以使用以下方法将值以数字方式处理为 SDF 有效数字:

ROUND(值,SDF-(1+INT(LOG10(ABS(值)))))

此外,能够重用和更新计算很有用,因此为了使同一变量的计算能够逐步更新,我添加了一个检查(\cs_if_exist:NF #1 {\tl_new:N #1})来确定命令是否已经存在,以防止出现提示文档命令已存在的错误。

因此 MWE 变成

\documentclass{article}

\usepackage{xparse}

\usepackage{siunitx}
\usepackage{mathtools,amssymb}


\ExplSyntaxOn
\NewDocumentCommand {\MySFRound} {m O{6} m}
 {
     \cs_if_exist:NF #1 {\tl_new:N #1}
     \tl_set:Nx #1 { \fp_eval:n {  round( (#3) , (#2 - (1 + floor(ln(abs(#3))/ln(10)))) ) } }
     %ROUND(value,SDF-(1+INT(LOG10(ABS(value)))))
 }
\ExplSyntaxOff

\newcommand{\MySF}{6}

\begin{document}

\textbf{Quadratic Equation}: $x^2 + 40x + 2 = 0$ 

\renewcommand{\MySF}{4}

\newcommand{\qa}{1}
\newcommand{\qb}{40}
\newcommand{\qc}{2}

\MySFRound{\QuadratictOne}[\MySF]{(1/2)*(1/\qa)*(-\qb)}
\MySFRound{\QuadratictTwo}[\MySF]{(1/2)*(1/\qa)*(((\qb)^2-(4*\qa*\qc))^(1/2))}

\MySFRound{\QuadraticxOne}[\MySF]{\QuadratictOne+\QuadratictTwo}
\MySFRound{\QuadraticxTwo}[\MySF]{\QuadratictOne-\QuadratictTwo}

\begin{align*}
t_1 &= \QuadratictOne\\
t_2 &= \QuadratictTwo\\
x_1 &= \QuadraticxOne\\
x_2 &= \QuadraticxTwo
\end{align*}

\end{document}

注意:在实现任意底数的对数之前,您可以使用ln(X)/ln(10)来求解log_10(X)expl3 数学函数中的对数

相关内容