5

How is the correct synatax to format in math or text?

Thanks for your help

enter image description here

\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} 

2 Answers 2

11

The problem is that _ is a letter in \ExplSyntaxOn. Use \sb instead. Also spaces are ignored, you have to escape them in expl3 with \. In addition, to get correct spacing don't enclose x\sb{1}= with $ but the whole line. Also you should replace \ifnum\fp_eval:n with \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}

Note however that the algorithm you use isn't numerical stable and therefore your solutions might be wrong.

A slightly more numerical stable version of the algorithm (which takes more time and doesn't seem worth it for most examples, imho) would be:

\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 ) } }$
    }
}
12
  • Btw: You could really replace \ifnum by \int_compare...
    – TeXnician
    Nov 7, 2017 at 12:32
  • @TeXnician you're right, didn't thought of checking other control sequences.
    – Skillmon
    Nov 7, 2017 at 12:33
  • @TeXnican, this is good idea. But how can I find all this commands?
    – user139826
    Nov 7, 2017 at 12:34
  • 3
    @Thomas If you use expl3 you should definitely know interface3.pdf.
    – TeXnician
    Nov 7, 2017 at 12:34
  • @Skillmon I changed “can” into “should”. It could be \int_compare:nNnTF, but only if integers are supposed to be given as argument.
    – egreg
    Nov 7, 2017 at 12:45
4

I know my answer is slightly off-topic. However there was in comments to main answer some discussion about numerical stability. With xint which computes algebra exactly you don't have to worry about whether some subtraction will induce lost digits; sure the square-root must be approximated but once done, all other computations being exact need no tricks about how to do the algebra best.

The second point is that there is a difficulty with siunitx's \num parsing being done before expansion of its argument. I had no such problem with for example \numprint macro from numprint package. So second point of answer is to explain how to use siunitx's \num with arguments evaluated via xint computations.

\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}

enter image description here

4
  • s/and/und/g...
    – user4686
    Nov 8, 2017 at 10:59
  • thank you for your slightly off-topic answer. I have already noticed that your package xint is very powerful. And thank you for explaining why there are problems with the num-macro.
    – user139826
    Nov 8, 2017 at 12:36
  • @Thomas thanks for kind words. Unfortunately xint currently only knows square root... (I am planning to extend it, but already delayed 2 years doing it). The num macro must have its reasons for not expanding its argument before it parses it. One only needs to be aware of it so that one uses a variant macro which does this expansion if it is needed.
    – user4686
    Nov 8, 2017 at 12:54
  • I wish you enough muse to make good progress with your extension of your xint package. I use some of your examples in a modified form for my admittedly simple calculations, as they are needed at German grammar schools. Thanks for that.
    – user139826
    Nov 8, 2017 at 13:13

You must log in to answer this question.