diff options
author | Karl Berry <karl@freefriends.org> | 2017-03-08 23:01:35 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-03-08 23:01:35 +0000 |
commit | 6fca20c09474a7f6a3559af1c984243a83669f61 (patch) | |
tree | cbfda048c91853241ef903a84a088c1e3a66fd50 /Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx | |
parent | ddbc1f2a5f193876d6f1df544e286029c6d671f8 (diff) |
l3 (8mar17)
git-svn-id: svn://tug.org/texlive/trunk@43432 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx | 189 |
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} |