带有宏的文本和数学输出格式不正确

带有宏的文本和数学输出格式不正确

数学或文本格式的正确语法是什么?

感谢您的帮助

在此处输入图片描述

\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx}

\ExplSyntaxOn

\NewDocumentCommand{\quadSol}{mmm}
 {% #1 = a, #2 = b, #3 = c  in  ax^2 + bx + c
  \group_begin:
   { \thomas_quadSol_step:nnn { #1 } { #2 } { #3 } }
  \group_end:
 }

\cs_new_protected:Nn \thomas_quadSol_step:nnn
 {
   \ifnum \fp_eval:n{#2*#2-4*#1*#3} <0 {\quad Die Gleichung hat keine reellen Lösungen } 
   \else
     $x_{1}=$
     \num{ \fp_eval:n { round( (-#2+sqrt((#2)^2-4*#1*#3))/(2*#1), 2 ) } }
     \quad
     $x_{2}=$
     \num{ \fp_eval:n { round( (-#2-sqrt((#2)^2-4*#1*#3))/(2*#1), 2 ) } }
   \fi
 }

\ExplSyntaxOff

\begin{document}

\quadSol{1}{2}{5}

\quadSol{1}{2}{-5}

\end{document} 

答案1

问题是 是_中的字母\ExplSyntaxOn。请使用\sb代替。空格也会被忽略,您必须使用 来转义它们expl3\此外,要获得正确的间距,请不要使用x\sb{1}=来括$起整个行。您还应该用\ifnum\fp_eval:n替换\fp_compare:nNnTF

\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx}

\ExplSyntaxOn

\NewDocumentCommand{\quadSol}{mmm}
 {% #1 = a, #2 = b, #3 = c  in  ax^2 + bx + c
  \group_begin:
   { \thomas_quadSol_step:nnn { #1 } { #2 } { #3 } }
  \group_end:
 }

\cs_new_protected:Nn \thomas_quadSol_step:nnn
 {
  \fp_compare:nNnTF { #2*#2-4*#1*#3 } < { 0 }
    {\quad Die\ Gleichung\ hat\ keine\ reellen\ Lösungen } 
    {
     $x\sb{1}=
     \num{ \fp_eval:n { round( (-#2+sqrt((#2)^2-4*#1*#3))/(2*#1), 2 ) } }
     \quad\lor\quad
     x\sb{2}=
     \num{ \fp_eval:n { round( (-#2-sqrt((#2)^2-4*#1*#3))/(2*#1), 2 ) } }$
    }
 }

\ExplSyntaxOff

\begin{document}

\quadSol{1}{2}{5}

\quadSol{1}{2}{-5}

\end{document}

但请注意,您使用的算法不是数值稳定的,因此您的解决方案可能是错误的。

该算法的数值稳定性略高一些的版本(在我看来,这会花费更多时间,而且对于大多数示例来说似乎不值得)将是:

\cs_new_protected:Nn \thomas_quadSol_stable:nnn
{
  \fp_compare:nNnTF { #2 * #2 } < { 4 * #1 * #3 }
    {\quad Die\ Gleichung\ hat\ keine\ reellen\ Lösungen } 
    {
      \fp_set:Nn \l_tmpa_fp { #2 / (2*#1) } % p in pq-formel
      \fp_set:Nn \l_tmpb_fp { #3 / #1 } % q in pq-formel
      \fp_compare:nNnTF { \l_tmpa_fp } < { 0 }
        {
          \fp_set:Nn \l_tmpa_fp
            { sqrt( \l_tmpa_fp*\l_tmpa_fp - \l_tmpb_fp ) - \l_tmpa_fp }
        }{
          \fp_set:Nn \l_tmpa_fp
            { - sqrt( \l_tmpa_fp*\l_tmpa_fp - \l_tmpb_fp ) - \l_tmpa_fp }
        }
      \fp_set:Nn \l_tmpb_fp { \l_tmpb_fp / \l_tmpa_fp }
      $x\sb{1}=
      \num{ \fp_eval:n { round( \l_tmpb_fp , 2 ) } }
      \quad\lor\quad
      x\sb{2}=
      \num{ \fp_eval:n { round( \l_tmpa_fp , 2 ) } }$
    }
}

答案2

我知道我的回答有点离题。然而,在主要答案的评论中有一些关于数值稳定性的讨论。使用 xint 可以精确计算代数,您不必担心某些减法是否会导致数字丢失;当然,平方根必须是近似的,但一旦完成,所有其他计算都是精确的,不需要关于如何最好地进行代数运算的技巧。

第二点是,在扩展其参数之前对 进行解析存在困难siunitx\num例如,我在使用包\numprint中的宏时没有遇到这样的问题numprint。因此,答案的第二点是解释如何使用通过 xint 计算评估的参数siunitx\num

\documentclass[ngerman]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{siunitx}
\usepackage{xintexpr}

% workaround problem with siunitx \num parsing before expanding
% workaround done in a way allowing \num's optional parameters
\newcommand\numx[2][]{\begingroup\if\relax\detokenize{#1}\relax
                         \def\x{\endgroup\num}\else
                         \def\x{\endgroup\num[#1]}\fi
                      \expandafter\x\expandafter{\romannumeral-`0#2}}
% for example something like
% \numx[scientific-notation=true]{\xinttheiexpr[#1] x2\relax}
% in code below would work.

% when using numprint's \np I encountered no problem like the \num's ones
% no workaround as in the above appeared necessary then
% \usepackage[autolanguage, np]{numprint}
% \let\numx\np

\newcommand\quadSol[4][2]{%
% #1 = user specified fixed point precision for rounding the output
% #2 = a, #3 = b, #4 = c  in  ax^2 + bx + c
% IT IS ASSUMED a IS NOT ZERO
  Die Gleichung mit $a=#2$, $b=#3$, $c=#4$ hat
  \begingroup
%
% \xintdefvar does computations exactly with rational numbers
% the sqrt(x) function computes with the prevailing float
% precision set by \xintDigits. Default: 16 decimal digits.
% one can also do sqrt(x, P) for using another precision.
%
% \xinttheiexpr[N] does exact computation like \xintdefvar
% or \xinttheexpr, but it rounds final result to N decimal digits
% after decimal mark. There is no removal of trailing
% zeroes (this should be job of formatting macro).
% 
    \xintdefvar a := #2;%
    \xintdefvar b := #3;%
    \xintdefvar c := #4;%
    \xintdefvar Delta := b*b - 4a*c;%
    \xintifSgn{\xinttheexpr sgn(Delta)\relax}
       {keine reellen Lösungen.}
       {eine doppelte Lösung
            ${}\approx\numx{\xinttheiexpr[#1] -b/2a\relax}$.}
       {zwei Lösungen
% We don't have to worry about numerical unstability because
% \xintdefvar (contrarily to \xintdeffloatvar) computes exactly!
% All the "loss" is in the square-root...
% By the way, let's compute it once only
% (use sqrt(Delta, P) for other precision P).
        \xintdefvar sqrtDelta := sqrt(Delta);% 
% The order x1, x2 is chosen to get x1 < x2 if a>0
        \xintdefvar x1 := (-b-sqrtDelta)/2a;%
        \xintdefvar x2 := (-b+sqrtDelta)/2a;%
%
% if we had been worried about numerical stability, we would have first
% defined x1 (if b>0) then get x2 by c/a/x1 formula.
% 
% but we are not worried because we compute exactly...
% once the square root is approximated as a floating point number (by default
% with 16 digits of precision).
%
% Raw output from \xinttheexpr can not be fed to \num as it is in A/B[X]
% format. So we use \xinttheiexpr[N] (fixed-point) or \xintthefloatexpr[N]
% (floating-point, uses scientific notation only if exponent is out of
%  -5,..,5 range as in Maple output).
%
        $x_{1}\approx \numx{\xinttheiexpr[#1] x1\relax}$
        and 
        $x_{2}\approx \numx{\xinttheiexpr[#1] x2\relax}$.
  %\par
  % Their sum is 
  %       $x_1 + x_2 \approx \numx{\xinttheiexpr[#1] x1 + x2\relax}$, and their product
  %       ix $x_1 x_2 \approx \numx{\xinttheiexpr[#1] x1*x2\relax}$.
}%
  \endgroup\par\medskip
}

\begin{document}

\quadSol{1}{2}{5}

\quadSol{1}{2}{-5}

\quadSol{1}{200}{1}

\quadSol[12]{1}{200}{1}

\quadSol{1}{10000}{1}

\quadSol[12]{1}{10000}{1}

% \quadSol{1}{-\xinttheiexpr[2] 1.73+3.27\relax}{\xinttheiexpr[4] 1.73*3.27\relax}

\end{document}

在此处输入图片描述

相关内容