diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx | 176 |
1 files changed, 93 insertions, 83 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx index d085fd70484..8c60c2a3246 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx @@ -22,8 +22,8 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-expo.dtx 6943 2017-02-17 16:47:59Z bruno $ - {L3 Floating-point exponential-related functions} +\def\ExplFileDate{2017/03/18} +\def\ExplFileVersion{7019} \begin{document} \DocInput{\jobname.dtx} \end{document} @@ -62,6 +62,20 @@ %<@@=fp> % \end{macrocode} % +% \begin{macro}[aux, EXP] +% { +% \@@_parse_word_exp:N , +% \@@_parse_word_ln:N , +% } +% Unary functions. +% \begin{macrocode} +\cs_new:Npn \@@_parse_word_exp:N + { \@@_parse_unary_function:NNN \@@_exp_o:w ? } +\cs_new:Npn \@@_parse_word_ln:N + { \@@_parse_unary_function:NNN \@@_ln_o:w ? } +% \end{macrocode} +% \end{macro} +% % \subsection{Logarithm} % % \subsubsection{Work plan} @@ -118,15 +132,15 @@ % Those are needed in the implementation. It turns out that we don't % need the value of $\ln(5)$. % \begin{macrocode} -\tl_const:Nn \c_@@_ln_i_fixed_tl { {0000}{0000}{0000}{0000}{0000}{0000} } -\tl_const:Nn \c_@@_ln_ii_fixed_tl { {6931}{4718}{0559}{9453}{0941}{7232} } -\tl_const:Nn \c_@@_ln_iii_fixed_tl {{10986}{1228}{8668}{1096}{9139}{5245} } -\tl_const:Nn \c_@@_ln_iv_fixed_tl {{13862}{9436}{1119}{8906}{1883}{4464} } -\tl_const:Nn \c_@@_ln_vi_fixed_tl {{17917}{5946}{9228}{0550}{0081}{2477} } -\tl_const:Nn \c_@@_ln_vii_fixed_tl {{19459}{1014}{9055}{3133}{0510}{5353} } -\tl_const:Nn \c_@@_ln_viii_fixed_tl{{20794}{4154}{1679}{8359}{2825}{1696} } -\tl_const:Nn \c_@@_ln_ix_fixed_tl {{21972}{2457}{7336}{2193}{8279}{0490} } -\tl_const:Nn \c_@@_ln_x_fixed_tl {{23025}{8509}{2994}{0456}{8401}{7991} } +\tl_const:Nn \c_@@_ln_i_fixed_tl { {0000}{0000}{0000}{0000}{0000}{0000};} +\tl_const:Nn \c_@@_ln_ii_fixed_tl { {6931}{4718}{0559}{9453}{0941}{7232};} +\tl_const:Nn \c_@@_ln_iii_fixed_tl {{10986}{1228}{8668}{1096}{9139}{5245};} +\tl_const:Nn \c_@@_ln_iv_fixed_tl {{13862}{9436}{1119}{8906}{1883}{4464};} +\tl_const:Nn \c_@@_ln_vi_fixed_tl {{17917}{5946}{9228}{0550}{0081}{2477};} +\tl_const:Nn \c_@@_ln_vii_fixed_tl {{19459}{1014}{9055}{3133}{0510}{5353};} +\tl_const:Nn \c_@@_ln_viii_fixed_tl{{20794}{4154}{1679}{8359}{2825}{1696};} +\tl_const:Nn \c_@@_ln_ix_fixed_tl {{21972}{2457}{7336}{2193}{8279}{0490};} +\tl_const:Nn \c_@@_ln_x_fixed_tl {{23025}{8509}{2994}{0456}{8401}{7991};} % \end{macrocode} % \end{variable} % @@ -303,7 +317,8 @@ % not the end result, we need to know it with more accuracy % (on the other hand, the ending is much simpler, as we don't % need an exact rounding for transcendental functions, but just -% a faithful rounding).\footnote{Bruno: to be completed.} +% a faithful rounding). +% ^^A todo: doc % % \begin{quote} % \cs{@@_ln_x_iv:wnnnnnnnn} @@ -343,10 +358,9 @@ \__int_value:w \__int_eval:w 1000000 + #2 #3 / #1 ; % Q6 } % \end{macrocode} -% We now have essentially\footnote{Bruno: add a mention that -% the error on $Q_{6}$ is bounded by $10$ (probably $6.7$), -% and thus corresponds to an error of $10^{-23}$ on the final -% result, small enough in all cases.} +% We now have essentially +% ^^A todo: determine error on $Q_{6}$ (probably $6.7$), +% ^^A todo: conclude the final result is off by $<10^{-23}$ % \begin{quote} % \cs{@@_ln_div_after:Nw} \meta{fixed tl} % \cs{@@_div_significand_pack:NNN} $10^6 + Q_{1}$ @@ -449,7 +463,7 @@ % \cs{@@_ln_Taylor:wwNw} % \Arg{T_1} \Arg{T_2} \Arg{T_3} \Arg{T_4} \Arg{T_5} \Arg{T_6} |;| |;| % \Arg{(2t)_1} \Arg{(2t)_2} \Arg{(2t)_3} \Arg{(2t)_4} \Arg{(2t)_5} \Arg{(2t)_6} |;| -% |{| \cs{@@_ln_c:NwNn} \meta{sign} |}| +% |{| \cs{@@_ln_c:NwNw} \meta{sign} |}| % \meta{fixed tl} \meta{exponent} |;| \meta{continuation} % \end{quote} % And we want to compute @@ -467,7 +481,7 @@ % \mul B; T; {\loop 3;} % \loop 3; C; % \end{verbatim} -% \footnote{Bruno: add explanations.} +% ^^A todo: doc % % This uses the routine for dividing a number by a small integer % (${}<10^4$). @@ -479,7 +493,7 @@ \if_int_compare:w #1 = 1 \exp_stop_f: \@@_ln_Taylor_break:w \fi: - \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl ; #1; + \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1; \@@_fixed_add:wwn #2; \@@_fixed_mul:wwn #3; { @@ -511,7 +525,7 @@ % For now, $\ln(x)$ is given as $\cdot 10^0$. Unless both the exponent % is $1$ and $c=1$, we shift to working in units of $\cdot 10^4$, % since the final result will be at least $\ln(10/7) \simeq -% 0.35$.\footnote{Bruno: that was wrong at some point, I must check.} +% 0.35$. % \begin{macrocode} \cs_new:Npn \@@_ln_c:NwNw #1 #2; #3 { @@ -520,10 +534,9 @@ \else: \exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_add:wwn \fi: - #3 ; #2 ; + #3 #2 ; } % \end{macrocode} -% \footnote{Bruno: this \emph{\textbf{must}} be updated with correct values!} % \end{macro} % % \begin{macro}{\@@_ln_exponent:wn} @@ -546,7 +559,7 @@ \cs_new:Npn \@@_ln_exponent:wn #1; #2 { \if_case:w #2 \exp_stop_f: - 0 \@@_case_return:nw { \@@_fixed_to_float:Nw 2 } + 0 \@@_case_return:nw { \@@_fixed_to_float_o:Nw 2 } \or: \exp_after:wN \@@_ln_exponent_one:ww \__int_value:w \else: @@ -569,8 +582,8 @@ \cs_new:Npn \@@_ln_exponent_one:ww 1; #1; { 0 - \exp_after:wN \@@_fixed_sub:wwn \c_@@_ln_x_fixed_tl ; #1; - \@@_fixed_to_float:wN 0 + \exp_after:wN \@@_fixed_sub:wwn \c_@@_ln_x_fixed_tl #1; + \@@_fixed_to_float_o:wN 0 } % \end{macrocode} % For small exponents, we just drop one block of digits, and set the @@ -582,11 +595,11 @@ { 4 \exp_after:wN \@@_fixed_mul:wwn - \c_@@_ln_x_fixed_tl ; + \c_@@_ln_x_fixed_tl {#3}{0000}{0000}{0000}{0000}{0000} ; #2 {0000}{#4}{#5}{#6}{#7}{#8}; - \@@_fixed_to_float:wN #1 + \@@_fixed_to_float_o:wN #1 } % \end{macrocode} % \end{macro} @@ -602,7 +615,7 @@ \if_case:w #2 \exp_stop_f: \@@_case_return_o:Nw \c_one_fp \or: - \exp_after:wN \@@_exp_normal:w + \exp_after:wN \@@_exp_normal_o:w \or: \if_meaning:w 0 #3 \exp_after:wN \@@_case_return_o:Nw @@ -619,64 +632,62 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_exp_normal:w, \@@_exp_pos:Nnwnw} +% \begin{macro}[aux, EXP]{\@@_exp_normal_o:w, \@@_exp_pos_o:Nnwnw, \@@_exp_overflow:NN} % \begin{macrocode} -\cs_new:Npn \@@_exp_normal:w \s_@@ \@@_chk:w 1#1 +\cs_new:Npn \@@_exp_normal_o:w \s_@@ \@@_chk:w 1#1 { \if_meaning:w 0 #1 - \@@_exp_pos:NNwnw + \@@_fixed_to_float:wN + \@@_exp_pos_o:NNwnw + \@@_fixed_to_float_o:wN \else: - \@@_exp_pos:NNwnw - \@@_fixed_inv_to_float:wN + \@@_exp_pos_o:NNwnw - \@@_fixed_inv_to_float_o:wN \fi: } -\cs_new:Npn \@@_exp_pos:NNwnw #1#2#3 \fi: #4#5; +\cs_new:Npn \@@_exp_pos_o:NNwnw #1#2#3 \fi: #4#5; { \fi: - \exp_after:wN \@@_sanitize:Nw - \exp_after:wN 0 - \__int_value:w #1 \__int_eval:w - \if_int_compare:w #4 < - \c_@@_half_prec_int - 1 - \exp_after:wN \@@_add_big_i_o:wNww - \__int_value:w \__int_eval:w 1 - #4 ; - 0 {1000}{0000}{0000}{0000} ; #5; - \exp:w - \else: - \if_int_compare:w #4 > \c_@@_max_exp_exponent_int - \exp_after:wN \@@_exp_overflow: - \exp:w + \if_int_compare:w #4 > \c_@@_max_exp_exponent_int + \token_if_eq_charcode:NNTF + #1 + { \@@_exp_overflow:NN \@@_overflow:w \c_inf_fp } + { \@@_exp_overflow:NN \@@_underflow:w \c_zero_fp } + \exp:w + \else: + \exp_after:wN \@@_sanitize:Nw + \exp_after:wN 0 + \__int_value:w #1 \__int_eval:w + \if_int_compare:w #4 < 0 \exp_stop_f: + \exp_after:wN \use_i:nn \else: - \if_int_compare:w #4 < 0 \exp_stop_f: - \exp_after:wN \use_i:nn - \else: - \exp_after:wN \use_ii:nn - \fi: - { - 0 - \@@_decimate:nNnnnn { - #4 } - \@@_exp_Taylor:Nnnwn - } - { - \@@_decimate:nNnnnn { \c_@@_prec_int - #4 } - \@@_exp_pos_large:NnnNwn - } - #5 - {#4} - #1 #2 0 - \exp:w + \exp_after:wN \use_ii:nn \fi: - \fi: + { + 0 + \@@_decimate:nNnnnn { - #4 } + \@@_exp_Taylor:Nnnwn + } + { + \@@_decimate:nNnnnn { \c_@@_prec_int - #4 } + \@@_exp_pos_large:NnnNwn + } + #5 + {#4} + #1 #2 0 + \exp:w + \fi: \exp_after:wN \exp_end: } -\cs_new:Npn \@@_exp_overflow: - { + 2 * \c_@@_max_exponent_int ; {1000} {0000} {0000} {0000} ; } +\cs_new:Npn \@@_exp_overflow:NN #1#2 + { + \exp_after:wN \exp_after:wN + \exp_after:wN #1 + \exp_after:wN #2 + } % \end{macrocode} % \end{macro} % % \begin{macro}[int, EXP]{\@@_exp_Taylor:Nnnwn} % \begin{macro}[aux, EXP]{\@@_exp_Taylor_loop:www, \@@_exp_Taylor_break:Nww} % This function is called for numbers in the range $[10^{-9}, -% 10^{-1})$. Our only task is to compute the Taylor series. The +% 10^{-1})$. We compute $10$ terms of the Taylor series. The % first argument is irrelevant (rounding digit used by some other % functions). The next three arguments, at least $16$ digits, % delimited by a semicolon, form a fixed point number, so we pack it @@ -748,7 +759,6 @@ \exp_after:wN \exp_after:wN \cs:w @@_exp_large_ \__int_to_roman:w #6 :wN \exp_after:wN \cs_end: \exp_after:wN \c_@@_one_fixed_tl - \exp_after:wN ; \__int_value:w #3 #4 \exp_stop_f: #5 00000 ; } @@ -890,14 +900,14 @@ % Then test the sign of $a$. % \begin{itemize} % \item If it is positive, and $a$ is a normal number, call -% \cs{@@_pow_normal:ww} followed by the two \texttt{fp} $a$ and $b$. +% \cs{@@_pow_normal_o:ww} followed by the two \texttt{fp} $a$ and $b$. % For $a=+0$ or $+\inf$, call \cs{@@_pow_zero_or_inf:ww} instead, to % return either $+0$ or $+\infty$ as appropriate. % \item If $a$ is a \texttt{nan}, then skip to the next semicolon % (which happens to be conveniently the end of $b$) and return % \texttt{nan}. % \item Finally, if $a$ is negative, compute $|a|^b$ -% (\cs{@@_pow_normal:ww} which ignores the sign of its first +% (\cs{@@_pow_normal_o:ww} which ignores the sign of its first % operand), and keep an extra copy of $a$ and $b$ (the second brace % group, containing \{~$b$~$a$~\}, is inserted between $a$ and $b$). % Then do some tests to find the final sign of the result if it @@ -920,7 +930,7 @@ \fi: { \if_meaning:w 1 #1 - \exp_after:wN \@@_pow_normal:ww + \exp_after:wN \@@_pow_normal_o:ww \else: \exp_after:wN \@@_pow_zero_or_inf:ww \fi: @@ -968,7 +978,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_pow_normal:ww} +% \begin{macro}[aux, EXP]{\@@_pow_normal_o:ww} % We have in front of us $a$, and $b\neq 0$, we know that $a$ is a % normal number, and we wish to compute $\lvert a\rvert^{b}$. If % $\lvert a\rvert=1$, we return $1$, unless $a=-1$ and $b$ is @@ -977,13 +987,13 @@ % a\rvert\neq 1$, test the type of $b$: % \begin{itemize} % \item[0] Impossible, we already filtered $b=\pm 0$. -% \item[1] Call \cs{@@_pow_npos:ww}. +% \item[1] Call \cs{@@_pow_npos_o:Nww}. % \item[2] Return $+\infty$ or $+0$ depending on the sign of $b$ and % whether the exponent of $a$ is positive or not. % \item[3] Return $b$. % \end{itemize} % \begin{macrocode} -\cs_new:Npn \@@_pow_normal:ww +\cs_new:Npn \@@_pow_normal_o:ww \s_@@ \@@_chk:w 1 #1#2#3; \s_@@ \@@_chk:w #4#5 { \if_int_compare:w \__str_if_eq_x:nn { #2 #3 } @@ -995,7 +1005,7 @@ \fi: \if_case:w #4 \exp_stop_f: \or: - \exp_after:wN \@@_pow_npos:Nww + \exp_after:wN \@@_pow_npos_o:Nww \exp_after:wN #5 \or: \if_meaning:w 2 #5 \exp_after:wN \reverse_if:N \fi: @@ -1016,7 +1026,7 @@ % \end{macro} % % ^^A todo: check that we compute ln to 21 digits! -% \begin{macro}[aux, EXP]{\@@_pow_npos:Nww} +% \begin{macro}[aux, EXP]{\@@_pow_npos_o:Nww} % We now know that $a\neq\pm 1$ is a normal number, and $b$ is a % normal number too. We want to compute $\lvert a\rvert^{b} = (\lvert % x\rvert\cdot 10^{n})^{y\cdot 10^{p}} = \exp((\ln\lvert x\rvert + n @@ -1029,7 +1039,7 @@ % is negative, negate that decimal exponent, and prepare to take the % inverse when converting from the fixed point to the floating point result. % \begin{macrocode} -\cs_new:Npn \@@_pow_npos:Nww #1 \s_@@ \@@_chk:w 1#2#3 +\cs_new:Npn \@@_pow_npos_o:Nww #1 \s_@@ \@@_chk:w 1#2#3 { \exp_after:wN \@@_sanitize:Nw \exp_after:wN 0 @@ -1037,11 +1047,11 @@ \if:w #1 \if_int_compare:w #3 > 0 \exp_stop_f: 0 \else: 2 \fi: \exp_after:wN \@@_pow_npos_aux:NNnww \exp_after:wN + - \exp_after:wN \@@_fixed_to_float:wN + \exp_after:wN \@@_fixed_to_float_o:wN \else: \exp_after:wN \@@_pow_npos_aux:NNnww \exp_after:wN - - \exp_after:wN \@@_fixed_inv_to_float:wN + \exp_after:wN \@@_fixed_inv_to_float_o:wN \fi: {#3} } @@ -1062,7 +1072,7 @@ \@@_pow_exponent:wnN {#3} \@@_fixed_mul:wwn #8 {0000}{0000} ; \@@_pow_B:wwN #7; - #1 #2 0 % fixed_to_float:wN + #1 #2 0 % fixed_to_float_o:wN } \cs_new:Npn \@@_pow_exponent:wnN #1; #2 { @@ -1114,7 +1124,7 @@ \cs_new:Npn \@@_pow_C_overflow:w #1; #2; #3 { + 2 * \c_@@_max_exponent_int - \exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl ; + \exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl } \cs_new:Npn \@@_pow_C_neg:w #1 ; 1 { @@ -1138,7 +1148,7 @@ \fi: } \cs_new:Npn \@@_pow_C_pack:w - { \exp_after:wN \@@_exp_large_v:wN \c_@@_one_fixed_tl ; } + { \exp_after:wN \@@_exp_large_v:wN \c_@@_one_fixed_tl } % \end{macrocode} % \end{macro} %^^A end[todo] |