summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx189
1 files changed, 91 insertions, 98 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
index 5f9a05d834b..d085fd70484 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-%% File: l3fp-expo.dtx Copyright (C) 2011-2014,2016 The LaTeX3 Project
+%% File: l3fp-expo.dtx Copyright (C) 2011-2014,2016,2017 The LaTeX3 Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -22,7 +22,7 @@
%
%<*driver>
\documentclass[full]{l3doc}
-\GetIdInfo$Id: l3fp-expo.dtx 6805 2016-12-28 22:15:52Z joseph $
+\GetIdInfo$Id: l3fp-expo.dtx 6943 2017-02-17 16:47:59Z bruno $
{L3 Floating-point exponential-related functions}
\begin{document}
\DocInput{\jobname.dtx}
@@ -167,7 +167,7 @@
{ %^^A todo: ln(1) should be "exact zero", not "underflow"
\exp_after:wN \@@_sanitize:Nw
\__int_value:w % for the overall sign
- \if_int_compare:w #1 < \c_one
+ \if_int_compare:w #1 < 1 \exp_stop_f:
2
\else:
0
@@ -198,8 +198,8 @@
\__int_value:w
\if_case:w #1 \exp_stop_f:
\or:
- \if_int_compare:w #2 < \c_four
- \__int_eval:w \c_ten - #2
+ \if_int_compare:w #2 < 4 \exp_stop_f:
+ \__int_eval:w 10 - #2
\else:
6
\fi:
@@ -236,7 +236,7 @@
{ #1#2; {#3#4#5#6} {#7} }
\cs_new:Npn \@@_ln_x_iii_var:NNNNNw #1 #2#3#4#5 #6;
{
- #1#2#3#4#5 + \c_one ;
+ #1#2#3#4#5 + 1 ;
{#1#2#3#4#5} {#6}
}
% \end{macrocode}
@@ -476,7 +476,7 @@
{ \@@_ln_Taylor_loop:www 21 ; {0000}{0000}{0000}{0000}{0000}{0000} ; }
\cs_new:Npn \@@_ln_Taylor_loop:www #1; #2; #3;
{
- \if_int_compare:w #1 = \c_one
+ \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;
@@ -484,7 +484,7 @@
\@@_fixed_mul:wwn #3;
{
\exp_after:wN \@@_ln_Taylor_loop:www
- \__int_value:w \__int_eval:w #1 - \c_two ;
+ \__int_value:w \__int_eval:w #1 - 2 ;
}
#3;
}
@@ -546,11 +546,11 @@
\cs_new:Npn \@@_ln_exponent:wn #1; #2
{
\if_case:w #2 \exp_stop_f:
- \c_zero \@@_case_return:nw { \@@_fixed_to_float:Nw 2 }
+ 0 \@@_case_return:nw { \@@_fixed_to_float:Nw 2 }
\or:
\exp_after:wN \@@_ln_exponent_one:ww \__int_value:w
\else:
- \if_int_compare:w #2 > \c_zero
+ \if_int_compare:w #2 > 0 \exp_stop_f:
\exp_after:wN \@@_ln_exponent_small:NNww
\exp_after:wN 0
\exp_after:wN \@@_fixed_sub:wwn \__int_value:w
@@ -568,7 +568,7 @@
% \begin{macrocode}
\cs_new:Npn \@@_ln_exponent_one:ww 1; #1;
{
- \c_zero
+ 0
\exp_after:wN \@@_fixed_sub:wwn \c_@@_ln_x_fixed_tl ; #1;
\@@_fixed_to_float:wN 0
}
@@ -580,7 +580,7 @@
% \begin{macrocode}
\cs_new:Npn \@@_ln_exponent_small:NNww #1#2#3; #4#5#6#7#8#9;
{
- \c_four
+ 4
\exp_after:wN \@@_fixed_mul:wwn
\c_@@_ln_x_fixed_tl ;
{#3}{0000}{0000}{0000}{0000}{0000} ;
@@ -635,29 +635,29 @@
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN 0
\__int_value:w #1 \__int_eval:w
- \if_int_compare:w #4 < - \c_eight
- \c_one
+ \if_int_compare:w #4 < - \c_@@_half_prec_int
+ 1
\exp_after:wN \@@_add_big_i_o:wNww
- \__int_value:w \__int_eval:w \c_one - #4 ;
+ \__int_value:w \__int_eval:w 1 - #4 ;
0 {1000}{0000}{0000}{0000} ; #5;
\exp:w
\else:
- \if_int_compare:w #4 > \c_five % cf \c_@@_max_exponent_int
+ \if_int_compare:w #4 > \c_@@_max_exp_exponent_int
\exp_after:wN \@@_exp_overflow:
\exp:w
\else:
- \if_int_compare:w #4 < \c_zero
+ \if_int_compare:w #4 < 0 \exp_stop_f:
\exp_after:wN \use_i:nn
\else:
\exp_after:wN \use_ii:nn
\fi:
{
- \c_zero
+ 0
\@@_decimate:nNnnnn { - #4 }
\@@_exp_Taylor:Nnnwn
}
{
- \@@_decimate:nNnnnn { \c_sixteen - #4 }
+ \@@_decimate:nNnnnn { \c_@@_prec_int - #4 }
\@@_exp_pos_large:NnnNwn
}
#5
@@ -666,10 +666,10 @@
\exp:w
\fi:
\fi:
- \exp_after:wN \c_zero
+ \exp_after:wN \exp_end:
}
\cs_new:Npn \@@_exp_overflow:
- { + \c_two * \c_@@_max_exponent_int ; {1000} {0000} {0000} {0000} ; }
+ { + 2 * \c_@@_max_exponent_int ; {1000} {0000} {0000} {0000} ; }
% \end{macrocode}
% \end{macro}
%
@@ -695,7 +695,7 @@
{ \@@_exp_Taylor_loop:www 10 ; #1 ; #1 ; \s__stop }
\cs_new:Npn \@@_exp_Taylor_loop:www #1; #2; #3;
{
- \if_int_compare:w #1 = \c_one
+ \if_int_compare:w #1 = 1 \exp_stop_f:
\exp_after:wN \@@_exp_Taylor_break:Nww
\fi:
\@@_fixed_div_int:wwN #3 ; #1 ;
@@ -861,28 +861,31 @@
% \subsection{Power}
%
% Raising a number $a$ to a power $b$ leads to many distinct situations.
-% \begin{center}
+% \begin{center}\def\abs#1{\lvert #1\rvert}
% \begin{tabular}{>{$}c<{$}|*8{>{$}l<{$}}}
-% a^b &-\infty&-y &-n &\pm 0&+n &+y &+\infty&\nan \\
-% \hline
-% +\infty&+0 &+0 &+0 &+1&+\infty &+\infty&+\infty&\nan \\
-% 1<x &+0 &+x^{-y}&+x^{-n} &+1&+x^{n} &+x^{y} &+\infty&\nan \\
-% +1 &+1 &+1 &+1 &+1&+1 &+1 &+1 &+1 \\
-% 0<x<1 &+\infty&+x^{-y}&+x^{-n} &+1&+x^{n} &+x^{y} &+0 &\nan \\
-% +0 &+\infty&+\infty&+\infty &+1&+0 &+0 &+0 &\nan \\
-% -0 &\nan &\nan &\pm\infty &+1&\pm 0 &+0 &+0 &\nan \\
-% -1<-x<0&\nan &\nan &\pm x^{-n}&+1&\pm x^{n}&\nan &+0 &\nan \\
-% -1 &\nan &\nan &\pm 1 &+1&\pm 1 &\nan &\nan &\nan \\
-% -x<-1 &+0 &\nan &\pm x^{-n}&+1&\pm x^{n}&\nan &\nan &\nan \\
-% -\infty&+0 &+0 &\pm 0 &+1&\pm\infty&\nan &\nan &\nan \\
-% \nan &\nan &\nan &\nan &+1&\nan &\nan &\nan &\nan \\
+% a^b &-\infty &(-\infty,-0) &-p/5^k &\pm 0 &+p/5^k &(0,\infty) &+\infty &\nan \\ \hline
+% +\infty &+0 &\multicolumn{2}{c}{$+0$} &+1 &\multicolumn{2}{c}{$+\infty$} &+\infty &\nan \\
+% (1,\infty) &+0 &\multicolumn{2}{c}{$+\abs{a}^{b}$} &+1 &\multicolumn{2}{c}{$+\abs{a}^{b}$} &+\infty &\nan \\
+% +1 &+1 &\multicolumn{2}{c}{$+1$} &+1 &\multicolumn{2}{c}{$+1$} &+1 &+1 \\
+% (0,1) &+\infty &\multicolumn{2}{c}{$+\abs{a}^{b}$} &+1 &\multicolumn{2}{c}{$+\abs{a}^{b}$} &+0 &\nan \\
+% +0 &+\infty &\multicolumn{2}{c}{$+\infty$} &+1 &\multicolumn{2}{c}{$+0$} &+0 &\nan \\
+% -0 &+\infty &\nan &(-1)^p\infty &+1 &(-1)^p 0 &+0 &+0 &\nan \\
+% (-1,0) &+\infty &\nan &(-1)^p\abs{a}^{b} &+1 &(-1)^p\abs{a}^{b} &\nan &+0 &\nan \\
+% -1 &+1 &\nan &(-1)^p &+1 &(-1)^p &\nan &+1 &\nan \\
+% (-\infty,-1) &+0 &\nan &(-1)^p\abs{a}^{b} &+1 &(-1)^p\abs{a}^{b} &\nan &+\infty &\nan \\
+% -\infty &+0 &+0 &(-1)^p 0 &+1 &(-1)^p\infty &\nan &+\infty &\nan \\
+% \nan &\nan &\nan &\nan &+1 &\nan &\nan &\nan &\nan \\
% \end{tabular}
% \end{center}
+% We distinguished in this table the cases of finite (positive or
+% negative) exponents of the form $b=p/q$ with $q$~odd (hence
+% necessarily a power of~$5$), as $(-1)^{p/q}=(-1)^p$ is defined in that
+% case.
% One peculiarity of this operation is that $\nan^0 = 1^\nan = 1$,
% because this relation is obeyed for any number, even $\pm\infty$.
%
% \begin{macro}[int, EXP]+\@@_^_o:ww+
-% We cram a most of the tests into a single function to save csnames.
+% We cram most of the tests into a single function to save csnames.
% First treat the case $b=0$: $a^0=1$ for any $a$, even \texttt{nan}.
% Then test the sign of $a$.
% \begin{itemize}
@@ -935,9 +938,9 @@
% power or $\infty$ to a negative power, and $+\infty$ otherwise.
% Thus, if the type of $a$ and the sign of $b$ coincide, the result
% is~$0$, since those conveniently take the same possible values, $0$
-% and~$2$. Otherwise, either $a=\pm 0$ with $b<0$ and we have a
-% division by zero, or $a=\pm\infty$ and $b>0$ and the result is also
-% $+\infty$, but without any exception.
+% and~$2$. Otherwise, either $a=\pm\infty$ and $b>0$ and the result
+% is $+\infty$, or $a=\pm 0$ with $b<0$ and we have a division by zero
+% unless $b=-\infty$.
% \begin{macrocode}
\cs_new:Npn \@@_pow_zero_or_inf:ww
\s_@@ \@@_chk:w #1#2; \s_@@ \@@_chk:w #3#4
@@ -948,14 +951,17 @@
\if_meaning:w #1 #4
\@@_case_return_o:Nw \c_zero_fp
\fi:
- \if_meaning:w 0 #1
+ \if_meaning:w 2 #1
+ \@@_case_return_o:Nw \c_inf_fp
+ \fi:
+ \if_meaning:w 2 #3
+ \@@_case_return_o:Nw \c_inf_fp
+ \else:
\@@_case_use:nw
{
\@@_division_by_zero_o:NNww \c_inf_fp ^
\s_@@ \@@_chk:w #1 #2 ;
}
- \else:
- \@@_case_return_o:Nw \c_inf_fp
\fi:
\s_@@ \@@_chk:w #3#4
}
@@ -981,7 +987,7 @@
\s_@@ \@@_chk:w 1 #1#2#3; \s_@@ \@@_chk:w #4#5
{
\if_int_compare:w \__str_if_eq_x:nn { #2 #3 }
- { 1 {1000} {0000} {0000} {0000} } = \c_zero
+ { 1 {1000} {0000} {0000} {0000} } = 0 \exp_stop_f:
\if_int_compare:w #4 #1 = 32 \exp_stop_f:
\exp_after:wN \@@_case_return_ii_o:ww
\fi:
@@ -993,7 +999,7 @@
\exp_after:wN #5
\or:
\if_meaning:w 2 #5 \exp_after:wN \reverse_if:N \fi:
- \if_int_compare:w #2 > \c_zero
+ \if_int_compare:w #2 > 0 \exp_stop_f:
\exp_after:wN \@@_case_return_o:Nww
\exp_after:wN \c_inf_fp
\else:
@@ -1028,7 +1034,7 @@
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN 0
\__int_value:w
- \if:w #1 \if_int_compare:w #3 > \c_zero 0 \else: 2 \fi:
+ \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
@@ -1060,7 +1066,7 @@
}
\cs_new:Npn \@@_pow_exponent:wnN #1; #2
{
- \if_int_compare:w #2 > \c_zero
+ \if_int_compare:w #2 > 0 \exp_stop_f:
\exp_after:wN \@@_pow_exponent:Nwnnnnnw % n\ln(10) - (-\ln(x))
\exp_after:wN +
\else:
@@ -1092,7 +1098,7 @@
}
\cs_new:Npn \@@_pow_B:wwN #1#2#3#4#5#6; #7;
{
- \if_int_compare:w #7 < \c_zero
+ \if_int_compare:w #7 < 0 \exp_stop_f:
\exp_after:wN \@@_pow_C_neg:w \__int_value:w -
\else:
\if_int_compare:w #7 < 22 \exp_stop_f:
@@ -1107,7 +1113,7 @@
}
\cs_new:Npn \@@_pow_C_overflow:w #1; #2; #3
{
- + \c_two * \c_@@_max_exponent_int
+ + 2 * \c_@@_max_exponent_int
\exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl ;
}
\cs_new:Npn \@@_pow_C_neg:w #1 ; 1
@@ -1128,7 +1134,7 @@
\else:
\exp_after:wN \@@_pow_C_overflow:w \__int_value:w
\fi:
- \__int_eval:w #1 - \c_one \exp_after:wN ;
+ \__int_eval:w #1 - 1 \exp_after:wN ;
\fi:
}
\cs_new:Npn \@@_pow_C_pack:w
@@ -1145,7 +1151,7 @@
% undefined. This is invalid, unless $|a|^b$ turns out to be $+0$ or
% \texttt{nan}, in which case we return that as $a^b$. In particular,
% since the underflow detection occurs before \cs{@@_pow_neg:www} is
-% called, |(-0.1)**(12345.6)| will give $+0$ rather than complaining
+% called, |(-0.1)**(12345.67)| will give $+0$ rather than complaining
% that the sign is not defined.
% \begin{macrocode}
\cs_new:Npn \@@_pow_neg:www \s_@@ \@@_chk:w #1#2; #3; #4;
@@ -1153,7 +1159,7 @@
\if_case:w \@@_pow_neg_case:w #4 ;
\exp_after:wN \@@_pow_neg_aux:wNN
\or:
- \if_int_compare:w \__int_eval:w #1 / \c_two = \c_one
+ \if_int_compare:w \__int_eval:w #1 / 2 = 1 \exp_stop_f:
\@@_invalid_operation_o:Nww ^ #3; #4;
\exp:w \exp_end_continue_f:w
\exp_after:wN \exp_after:wN
@@ -1169,7 +1175,7 @@
\exp_after:wN \s_@@
\exp_after:wN \@@_chk:w
\exp_after:wN #2
- \__int_value:w \__int_eval:w \c_two - #3 \__int_eval_end:
+ \__int_value:w \__int_eval:w 2 - #3 \__int_eval_end:
}
% \end{macrocode}
% ^^A todo: is this \@@_exp_after_o:w necessary? Appropriate?
@@ -1178,66 +1184,53 @@
% \begin{macro}[aux, rEXP]
% {
% \@@_pow_neg_case:w, \@@_pow_neg_case_aux:nnnnn,
-% \@@_pow_neg_case_aux:NNNNNNNNw
+% \@@_pow_neg_case_aux:w
% }
-% This function expects a floating point number, and \enquote{returns}
-% $-1$ if it is an even integer, $0$ if it is an odd integer, and $1$
-% if it is not an integer. Zeros are even, $\pm\infty$ and
-% \texttt{nan} are non-integers. The sign of normal numbers is
-% irrelevant to parity. If the exponent is greater than sixteen, then
-% the number is even. If the exponent is non-positive, the number
-% cannot be an integer. We also separate the ranges of exponent
-% $[1,8]$ and $[9,16]$. In the former case, check that the last $8$
-% digits are zero (otherwise we don't have an integer). In both
-% cases, consider the appropriate $8$ digits, either |#4#5| or |#2#3|,
-% remove the first few: we are then left with \meta{digit}
-% \meta{digits} |;| which would be the digits surrounding the decimal
-% period. If the \meta{digits} are non-zero, the number is not an
-% integer. Otherwise, check the parity of the \meta{digit} and return
-% \cs{c_zero} or |-|\cs{c_one}.
+% This function expects a floating point number, and determines its
+% \enquote{parity}. It should be used after \cs{if_case:w} or in an
+% integer expression. It gives $-1$ if the number is an even integer
+% divided by some power of~$5$, $0$~if the number is an odd integer
+% divided by some power of~$5$, and $1$~otherwise. Zeros and
+% $\pm\infty$ are even (because very large finite floating points are
+% even), while \texttt{nan} is a non-integer. The sign of normal
+% numbers is irrelevant to parity. The idea is to repeatedly multiply
+% the number by~$5$ (by halving the mantissa and shifting the
+% exponent) until the mantissa is odd (this can only happen at most
+% $53$ times since $2^{54}>10^{16}$): if the resulting exponent is
+% larger than $16$ the parity is even, if it is exactly $16$ the
+% parity is odd, and otherwise we should return~$1$. Of course there
+% is a shortcut: we stop as soon as the exponent exceeds~$16$.
% \begin{macrocode}
\cs_new:Npn \@@_pow_neg_case:w \s_@@ \@@_chk:w #1#2#3;
{
\if_case:w #1 \exp_stop_f:
- -\c_one
+ -1
\or: \@@_pow_neg_case_aux:nnnnn #3
- \else: \c_one
+ \or: -1
+ \else: 1
\fi:
+ \exp_stop_f:
}
\cs_new:Npn \@@_pow_neg_case_aux:nnnnn #1#2#3#4#5
+ { \@@_pow_neg_case_aux:w #1 ; #2 #3 ; #4 #5 ; }
+\cs_new:Npn \@@_pow_neg_case_aux:w #1 ; #2 ; #3 ;
{
- \if_int_compare:w #1 > \c_eight
- \if_int_compare:w #1 > \c_sixteen
- -\c_one
- \else:
- \exp_after:wN \exp_after:wN
- \exp_after:wN \@@_pow_neg_case_aux:NNNNNNNNw
- \prg_replicate:nn { \c_sixteen - #1 } { 0 } #4#5 ;
- \fi:
+ \if_int_compare:w #1 > \c_@@_prec_int
+ -1
\else:
- \if_int_compare:w #1 > \c_zero
- \if_int_compare:w #4#5 = \c_zero
- \exp_after:wN \exp_after:wN
- \exp_after:wN \@@_pow_neg_case_aux:NNNNNNNNw
- \prg_replicate:nn { \c_eight - #1 } { 0 } #2#3 ;
+ \if_int_odd:w #3 \exp_stop_f:
+ \if_int_compare:w #1 = \c_@@_prec_int
+ 0
\else:
- \c_one
+ 1
\fi:
\else:
- \c_one
- \fi:
- \fi:
- }
-\cs_new:Npn \@@_pow_neg_case_aux:NNNNNNNNw #1#2#3#4#5#6#7#8#9;
- {
- \if_int_compare:w 0 #9 = \c_zero
- \if_int_odd:w #8 \exp_stop_f:
- \c_zero
- \else:
- -\c_one
+ \exp_after:wN \@@_pow_neg_case_aux:w
+ \__int_value:w \__int_eval:w #1 + 1 \exp_after:wN ;
+ \__int_value:w \__int_eval:w (#2 + 1) / 2 - 1 \exp_after:wN ;
+ \__int_value:w \__int_eval:w
+ \if_int_odd:w #2 \exp_stop_f: 5000 0000 + \fi: #3 / 2 ;
\fi:
- \else:
- \c_one
\fi:
}
% \end{macrocode}