diff options
author | Karl Berry <karl@freefriends.org> | 2012-08-31 17:58:55 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-08-31 17:58:55 +0000 |
commit | 3301423440393adfdbbcfa0d8471e4b4c63df1e6 (patch) | |
tree | 6aa86f66a252f654a2bd2f28ee7b680fdac1b0a3 /Master | |
parent | a511edd7e6a05e250f2b2d8062a470734e3af33d (diff) |
l3kernel 3160 (31aug12)
git-svn-id: svn://tug.org/texlive/trunk@27559 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
49 files changed, 2495 insertions, 1669 deletions
diff --git a/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf Binary files differindex 23fe9cdd425..9fce016693f 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf b/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf Binary files differindex e58e5afaaaa..078b6ba6ec5 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf Binary files differindex 5868f4cf1a4..7fc4478083e 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf Binary files differindex 7f0725051bb..eb85cd4ae51 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf Binary files differindex 68d31904d2e..faff73c2004 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3.pdf b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf Binary files differindex 4a44d224368..ec3908fb73a 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/source3.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index 5003992c6e0..24dd30934c9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx @@ -49,8 +49,8 @@ %<*driver|package> \def\ExplFileName{expl3} \def\ExplFileDescription{L3 Experimental code bundle wrapper} -\def\ExplFileDate{2012/08/14} -\def\ExplFileVersion{4091} +\def\ExplFileDate{2012/08/29} +\def\ExplFileVersion{4160} %</driver|package> %<*driver> \documentclass[full]{l3doc} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx index ec718e88d18..ed3580db09f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3alloc.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3alloc.dtx 4145 2012-08-27 20:30:30Z bruno $ {L3 Register allocation} %</driver|package> %<*driver> @@ -217,8 +217,8 @@ \seq_put_right:Nn \g__dim_allocation_seq {#1} \seq_put_right:Nn \g__int_allocation_seq {#1} \seq_put_right:Nn \g__skip_allocation_seq {#1} - \exp_args:Nf \@@_reserve_insert:n - { \etex_numexpr:D #1 + 1 \scan_stop: } + \exp_args:No \@@_reserve_insert:n + { \tex_the:D \etex_numexpr:D #1 + 1 \scan_stop: } } } \@@_reserve_insert:n { 221 } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index ede47fd6312..ac429fd8883 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3basics.dtx 4069 2012-08-08 23:12:57Z bruno $ +\GetIdInfo$Id: l3basics.dtx 4144 2012-08-27 19:37:16Z bruno $ {L3 Basic definitions} %</driver|package> %<*driver> @@ -1447,10 +1447,13 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\exp_args:Nc} +% \begin{macro}[EXP]{\exp_args:Nc, \exp_args:cc} % Discussed in \pkg{l3expan}, but needed much earlier. % \begin{macrocode} -\tex_long:D \tex_def:D \exp_args:Nc #1#2 { \exp_after:wN #1 \cs:w #2 \cs_end: } +\tex_long:D \tex_def:D \exp_args:Nc #1#2 + { \exp_after:wN #1 \cs:w #2 \cs_end: } +\tex_long:D \tex_def:D \exp_args:cc #1#2 + { \cs:w #1 \exp_after:wN \cs_end: \cs:w #2 \cs_end: } % \end{macrocode} % \end{macro} % @@ -1937,7 +1940,7 @@ \exp_after:wN \use_ii:nn \fi: { - \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 _p: #5 } #6 + \exp_args:cc { cs_ #2 #3 :Npn } { #4 _p: #5 } #6 { #7 \c_zero \c_true_bool \c_false_bool } } { @@ -1947,17 +1950,17 @@ } \cs_set_protected:Npn \__prg_generate_T_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7 { - \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 T } #6 + \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 T } #6 { #7 \c_zero \use:n \use_none:n } } \cs_set_protected:Npn \__prg_generate_F_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7 { - \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 F } #6 + \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 F } #6 { #7 \c_zero { } } } \cs_set_protected:Npn \__prg_generate_TF_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7 { - \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 TF } #6 + \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 TF } #6 { #7 \c_zero } } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index c7493dc6846..948976f4110 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -37,7 +37,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3clist.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3clist.dtx 4102 2012-08-15 16:08:27Z bruno $ {L3 Comma separated lists} %</driver|package> %<*driver> @@ -847,7 +847,7 @@ \cs_new_protected_nopar:Npn \clist_put_right:Nn { \@@_put_right:NNNn \clist_concat:NNN \clist_set:Nn } \cs_new_protected_nopar:Npn \clist_gput_right:Nn - { \@@_put_right:NNNn \clist_gconcat:NNN \clist_gset:Nn } + { \@@_put_right:NNNn \clist_gconcat:NNN \clist_set:Nn } \cs_new_protected:Npn \@@_put_right:NNNn #1#2#3#4 { #2 \l_@@_internal_clist {#4} @@ -1357,25 +1357,20 @@ % % \begin{macro}{\clist_show:N, \clist_show:c} % \begin{macro}{\clist_show:n} -% Apply the general \cs{__msg_show_variable:Nnn}. In the case +% Apply the general \cs{__msg_show_variable:Nnx}. In the case % of an \texttt{n}-type comma-list, first store it -% in a scratch variable, then show that variable, -% omitting its name from the $4$-th argument. +% in a scratch variable, then show that variable: +% The message takes care of omitting its name. % \begin{macrocode} \cs_new_protected:Npn \clist_show:N #1 { - \__msg_show_variable:Nnn - #1 - { clist } + \__msg_show_variable:Nnx #1 { clist } { \clist_map_function:NN #1 \__msg_show_item:n } } \cs_new_protected:Npn \clist_show:n #1 { \clist_set:Nn \l_@@_internal_clist {#1} - \__msg_show_variable:Nnn - \l_@@_internal_clist - { clist } - { \clist_map_function:NN \l_@@_internal_clist \__msg_show_item:n } + \clist_show:N \l_@@_internal_clist } \cs_generate_variant:Nn \clist_show:N { c } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index cc205d5da4a..1c7f4836804 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -36,7 +36,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3coffins.dtx 4011 2012-07-20 21:02:59Z joseph $ +\GetIdInfo$Id: l3coffins.dtx 4092 2012-08-14 14:04:41Z bruno $ {L3 Coffin code layer} %</driver|package> %<*driver> @@ -1676,7 +1676,7 @@ { \@@_if_exist:NT #1 { - \__msg_show_variable:Nnn #1 { coffins } + \__msg_show_variable:Nnx #1 { coffins } { \prop_map_function:cN { l_@@_poles_ \__int_value:w #1 _prop } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color.dtx index 3b1476f3714..caf5f258333 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3color.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3color.dtx @@ -36,8 +36,8 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3color.dtx 3991 2012-07-16 19:00:35Z joseph $ - {L3 Experimental colour support} +\GetIdInfo$Id: l3color.dtx 4156 2012-08-29 11:10:09Z joseph $ + {L3 Experimental color support} %</driver|package> %<*driver> \documentclass[full]{l3doc} @@ -68,14 +68,14 @@ % % \begin{documentation} % -% This module provides support for colour in \LaTeX3{}. At present, the +% This module provides support for color in \LaTeX3{}. At present, the % material here is mainly intended to support a small number of low-level % requirements in other \pkg{l3kernel} modules. % % \section{Colour in boxes} % -% Controlling the colour of text in boxes requires a small number of control -% functions, so that the boxed material uses the colour at the point where +% Controlling the color of text in boxes requires a small number of control +% functions, so that the boxed material uses the color at the point where % it is set, rather than where it is used. % % \begin{function}[added = 2011-09-03]{\color_group_begin:, \color_group_end:} @@ -84,14 +84,14 @@ % \ldots % \cs{color_group_end:} % \end{syntax} -% Creates a colour group: one used to \enquote{trap} colour settings. +% Creates a color group: one used to \enquote{trap} color settings. % \end{function} % % \begin{function}[added = 2011-09-03]{\color_ensure_current:} % \begin{syntax} % \cs{color_ensure_current:} % \end{syntax} -% Ensures that material inside a box will use the foreground colour +% Ensures that material inside a box will use the foreground color % at the point where the box is set, rather than that in force when the % box is used. This function should usually be used within a % \cs{color_group_begin:} \ldots \cs{color_group_end:} group. @@ -116,7 +116,7 @@ % \end{macrocode} % % \begin{macro}{\color_group_begin:, \color_group_end:} -% Grouping for colour is almost the same as using the basic \cs{group_begin:} +% Grouping for color is almost the same as using the basic \cs{group_begin:} % and \cs{group_end:} functions. However, in vertical mode the end-of-group % needs a \tn{par}, which in horizontal mode does nothing. % \begin{macrocode} @@ -130,8 +130,8 @@ % \end{macro} % % \begin{macro}{\color_ensure_current:} -% A driver-independent wrapper for setting the foreground colour to the -% current colour \enquote{now}. +% A driver-independent wrapper for setting the foreground color to the +% current color \enquote{now}. % \begin{macrocode} %<*initex> \cs_new_protected_nopar:Npn \color_ensure_current: @@ -140,7 +140,7 @@ % \end{macrocode} % In package mode, the driver code may not be loaded. To keep down % dependencies, if there is no driver code available and no \cs{set@color} -% then colour is not in use and this function can be a no-op. +% then color is not in use and this function can be a no-op. % \begin{macrocode} %<*package> \cs_new_protected_nopar:Npn \color_ensure_current: { } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index 8e0c1fd39e8..bea9cf251ce 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx @@ -78,7 +78,7 @@ Do not distribute a modified version of this file. %</driver|class> % %<*driver|class> -\GetIdInfo$Id: l3doc.dtx 4070 2012-08-09 11:04:46Z joseph $ +\GetIdInfo$Id: l3doc.dtx 4130 2012-08-20 21:30:22Z joseph $ {L3 Experimental documentation class} %</driver|class> % @@ -481,7 +481,7 @@ Do not distribute a modified version of this file. \tl_new:N \l_@@_macro_tl \int_new:N \l_@@_macro_int \int_new:N \g_@@_nested_macro_int -\int_new:N \g_@@_codeline_int +%\int_new:N \c@CodelineNo \prop_new:N \g_@@_missing_tests_prop \clist_new:N \g_docinput_clist \tl_new:N \l_@@_at_replaced_macro_tl @@ -1525,7 +1525,7 @@ Do not distribute a modified version of this file. \tl_to_str:N \l_@@_at_replaced_macro_tl }] } - \int_gincr:N \g_@@_codeline_int + \int_gincr:N \c@CodelineNo \bool_if:NF \l_@@_macro_aux_bool { @@ -1549,7 +1549,7 @@ Do not distribute a modified version of this file. \exp_args:Nx \DoNotIndex{ \tl_to_str:N \l_@@_at_replaced_macro_tl } } - \int_gdecr:N \g_@@_codeline_int + \int_gdecr:N \c@CodelineNo \ignorespaces } % \end{macrocode} @@ -2158,7 +2158,7 @@ Do not distribute a modified version of this file. \immediate\write\@indexfile { \string\indexentry{#1} - { \filesep \int_use:N \g_@@_codeline_int } + { \filesep \int_use:N \c@CodelineNo } } } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx index b088943d88c..6d6f17a4910 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx @@ -36,7 +36,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3drivers.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3drivers.dtx 4156 2012-08-29 11:10:09Z joseph $ {L3 Experimental drivers} %</driver|package> %<*driver> @@ -69,7 +69,7 @@ % \begin{documentation} % % \TeX{} relies on drivers in order to carry out a number of tasks, such -% as using colour, including graphics and setting up hyper-links. The nature +% as using color, including graphics and setting up hyper-links. The nature % of the code required depends on the exact driver in use. Currently, % \LaTeX3 is aware of the following drivers: % \begin{itemize} @@ -140,11 +140,11 @@ % \begin{syntax} % \cs{__driver_color_ensure_current:} % \end{syntax} -% Ensures that the colour used to typeset material is that which was +% Ensures that the color used to typeset material is that which was % set when the material was placed in a box. This function is therefore -% required inside any \enquote{colour safe} box to ensure that the box may -% be inserted in a location where the foreground colour has been altered, -% while preserving the colour used in the box. +% required inside any \enquote{color safe} box to ensure that the box may +% be inserted in a location where the foreground color has been altered, +% while preserving the color used in the box. % \end{function} % % \end{documentation} @@ -484,7 +484,7 @@ % \subsection{Colour support} % % \begin{variable}{\l_@@_current_color_tl} -% The current colour is needed by all of the engines, but the way this +% The current color is needed by all of the engines, but the way this % is stored varies. % \begin{macrocode} \tl_new:N \l_@@_current_color_tl @@ -502,7 +502,7 @@ % % \begin{variable}{\l_@@_color_stack_int} % \pdfTeX{} (version~1.40.0 or later) and \LuaTeX{} have multiple stacks -% available, and the colour stack therefore needs a number. +% available, and the color stack therefore needs a number. % \begin{macrocode} %<*pdfmode> \int_new:N \l_@@_color_stack_int @@ -512,8 +512,8 @@ % % \begin{macro}{\@@_color_ensure_current:} % \begin{macro}[aux]{\@@_color_reset:} -% Setting the current colour depends on the nature of the colour stack -% available. In all cases there is a need to reset the colour after +% Setting the current color depends on the nature of the color stack +% available. In all cases there is a need to reset the color after % the current group. % \begin{macrocode} %<*dvips|xdvipdfmx> diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index 5c853a3a321..d912433ee8d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3expan.dtx 4073 2012-08-10 01:33:13Z bruno $ +\GetIdInfo$Id: l3expan.dtx 4149 2012-08-28 10:50:40Z bruno $ {L3 Argument expansion} %</driver|package> %<*driver> @@ -116,7 +116,7 @@ % % \section{Methods for defining variants} % -% \begin{function}[updated = 2012-06-21]{\cs_generate_variant:Nn} +% \begin{function}[updated = 2012-08-28]{\cs_generate_variant:Nn} % \begin{syntax} % \cs{cs_generate_variant:Nn} \meta{parent control sequence} \Arg{variant argument specifiers} % \end{syntax} @@ -598,7 +598,7 @@ % with other functions using temporary variables. % \end{variable} % -% \begin{function}{\::n, \::N, \::c, \::o, \::f, \::x, \::v, \::V, \:::} +% \begin{function}{\::n, \::N, \::p, \::c, \::o, \::f, \::x, \::v, \::V, \:::} % \begin{syntax} % |\cs_set_nopar:Npn \exp_args:Ncof { \::c \::o \::f \::: }| % \end{syntax} @@ -644,11 +644,7 @@ % argument handling is defined. These general expansion functions are % expandable unless |x| is used. (Any version of |x| is going to have % to use one of the \LaTeX3 names for \cs{cs_set_nopar:Npx} at some -% point, and so is never going to be expandable.\footnote{Some -% primitives have certain characteristics that means that their -% arguments undergo an expansion similar to an \texttt{x} type -% expansion but the primitive is in fact still expandable. We make it -% very clear when such a function is expandable.}) +% point, and so is never going to be expandable.) % % The definition of expansion functions with this technique happens % in section~\ref{sec:gendef}. @@ -671,6 +667,8 @@ % \cs{:::} serves as an end marker for the list of manipulations, |#2| % is the carried over result of the previous expansion steps and |#3| is % the argument about to be processed. +% One exception to this rule is \cs{::p}, which has to grab an argument +% delimited by a left brace. % % \begin{macro}[aux, EXP]{\@@_arg_next:nnn} % \begin{macro}[aux, EXP]{\@@_arg_next:Nnn} @@ -713,9 +711,18 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[int, EXP]{\::p} +% This function is used to skip an argument that is delimited by a +% left brace and doesn't need to be expanded. It should not be +% wrapped in braces in the result. +% \begin{macrocode} +\cs_new:Npn \::p #1 \::: #2#3# { #1 \::: {#2#3} } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[int, EXP]{\::c} % This function is used to skip an argument that is turned into -% as control sequence without expansion. +% a control sequence without expansion. % \begin{macrocode} \cs_new:Npn \::c #1 \::: #2#3 { \exp_after:wN \@@_arg_next:Nnn \cs:w #3 \cs_end: {#1} {#2} } @@ -890,17 +897,14 @@ % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\exp_args:Nc} -% In \pkg{l3basics} -%\end{macro} +% \begin{macro}[EXP]{\exp_args:Nc, \exp_args:cc} +% In \pkg{l3basics}. +% \end{macro} % -% \begin{macro}[EXP] -% {\exp_args:cc, \exp_args:NNc, \exp_args:Ncc, \exp_args:Nccc} -% Here are the functions that turn their argument into csnames but -% are expandable. +% \begin{macro}[EXP]{\exp_args:NNc, \exp_args:Ncc, \exp_args:Nccc} +% Here are the functions that turn their argument into csnames but are +% expandable. % \begin{macrocode} -\cs_new:Npn \exp_args:cc #1#2 - { \cs:w #1 \exp_after:wN \cs_end: \cs:w #2 \cs_end: } \cs_new:Npn \exp_args:NNc #1#2#3 { \exp_after:wN #1 \exp_after:wN #2 \cs:w # 3\cs_end: } \cs_new:Npn \exp_args:Ncc #1#2#3 @@ -1283,43 +1287,60 @@ \exp_after:wN #1 \exp_after:wN \@@_generate_variant:nnNN \exp_after:wN #1 - \etex_detokenize:D {#2} , ? , \q_recursion_stop + \etex_detokenize:D {#2} , \scan_stop: , \q_recursion_stop } % \end{macrocode} % \end{macro} % % \begin{macro}[aux]{\@@_generate_variant:N} -% \begin{macro}[aux]{\@@_generate_variant:w} -% The idea here is to pick up protected parent functions, using the -% nature of the meaning string that they generate. If |\protected| -% appears in the meaning, the first \cs{q_mark} is taken as an -% argument, and |#3| is \cs{cs_new_protected_nopar:Npx}, otherwise it +% \begin{macro}[aux]{\@@_generate_variant:ww, \@@_generate_variant:wwNw} +% The goal here is to pick up protected parent functions. There are +% four cases: the parent function can be a primitive or a macro, and +% can be expandable or not. For non-expandable primitives, all +% variants should be protected; skipping the \cs{else:} branch is safe +% because all primitive \TeX{} conditionals are expandable. +% +% The other case where variants should be protected is when the parent +% function is a protected macro: then |protected| appears in the +% meaning before the fist occurrence of |macro|. The |ww| auxiliary +% removes everything in the meaning string after the first |ma|. We +% use |ma| rather than the full |macro| because the meaning of the +% \tn{firstmark} primitive (and four others) can contain an arbitrary +% string after a leading |firstmark:|. Then, look for |pr| in the +% part we extracted: no need to look for anything longer: the only +% strings we can have are an empty string, \verb*|\long |, +% \verb*|\protected |, \verb*|\protected\long |, |\first|, |\top|, +% |\bot|, |\splittop|, or |\splitbot|, with |\| replaced by the +% appropriate escape character. If |pr| appears in the part before +% |ma|, the first \cs{q_mark} is taken as an argument of the |wwNw| +% auxiliary, and |#3| is \cs{cs_new_protected_nopar:Npx}, otherwise it % is \cs{cs_new_nopar:Npx}. % \begin{macrocode} \group_begin: - \tex_lccode:D `\Z = `\d \scan_stop: - \tex_lccode:D `\? =`\\ \scan_stop: + \tex_catcode:D `\M = 12 \scan_stop: + \tex_catcode:D `\A = 12 \scan_stop: \tex_catcode:D `\P = 12 \scan_stop: \tex_catcode:D `\R = 12 \scan_stop: - \tex_catcode:D `\O = 12 \scan_stop: - \tex_catcode:D `\T = 12 \scan_stop: - \tex_catcode:D `\E = 12 \scan_stop: - \tex_catcode:D `\C = 12 \scan_stop: - \tex_catcode:D `\Z = 12 \scan_stop: \tex_lowercase:D { \group_end: \cs_new_protected:Npn \@@_generate_variant:N #1 { - \exp_after:wN \@@_generate_variant:w - \token_to_meaning:N #1 - \q_mark \cs_new_protected_nopar:Npx - ? PROTECTEZ - \q_mark \cs_new_nopar:Npx - \q_stop + \exp_after:wN \if_meaning:w \exp_not:N #1 #1 + \cs_set_eq:NN \@@_tmp:w \cs_new_protected_nopar:Npx + \else: + \exp_after:wN \@@_generate_variant:ww + \token_to_meaning:N #1 MA \q_mark + \q_mark \cs_new_protected_nopar:Npx + PR + \q_mark \cs_new_nopar:Npx + \q_stop + \fi: } - \cs_new_protected:Npn \@@_generate_variant:w - #1 ? PROTECTEZ #2 \q_mark #3 #4 \q_stop + \cs_new_protected:Npn \@@_generate_variant:ww #1 MA #2 \q_mark + { \@@_generate_variant:wwNw #1 } + \cs_new_protected:Npn \@@_generate_variant:wwNw + #1 PR #2 \q_mark #3 #4 \q_stop { \cs_set_eq:NN \@@_tmp:w #3 } @@ -1335,12 +1356,20 @@ % \item Boolean. % \item Base function. % \end{arguments} -% We discard the boolean and then set off a loop through the desired -% variant forms. The original function is retained as |#4| for +% If the boolean is \cs{c_false_bool}, the base function has no colon +% and we abort with an error; otherwise, set off a loop through the +% desired variant forms. The original function is retained as |#4| for % efficiency. % \begin{macrocode} \cs_new_protected:Npn \@@_generate_variant:nnNN #1#2#3#4 - { \@@_generate_variant:Nnnw #4 {#1}{#2} } + { + \if_meaning:w \c_false_bool #3 + \__msg_kernel_error:nnx { kernel } { missing-colon } + { \token_to_str:c {#1} } + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w + \fi: + \@@_generate_variant:Nnnw #4 {#1}{#2} + } % \end{macrocode} % \end{macro} % @@ -1351,108 +1380,232 @@ % \item Base signature. % \item Beginning of variant signature. % \end{arguments} -% First check whether to terminate the loop over variant forms. Then -% build the variant function name once, to avoid repeating this -% relatively expensive operation. Then recurse, calling -% \cs{@@_generate_variant:Nnnw} with the three same arguments (and a -% new item from the comma list of variant forms). -% -% For each variant form, construct a new function name using the +% First check whether to terminate the loop over variant forms. Then, +% for each variant form, construct a new function name using the % original base name, the variant signature consisting of $l$ letters % and the last $k-l$ letters of the base signature (of length $k$). % For example, for a base function \cs{prop_put:Nnn} which needs a -% |cV| variant form, we want the new signature to be |cVn|. This -% could be done by placing the variant form letters, then -% \cs{use_none:nn} followed by the signature (the choice of -% \cs{use_none:nn} would depend on the variant form). However, this -% would crash badly if the base signature is mistakenly shorter than -% the variant form (this includes cases where the base function had no -% colon). Instead, we do a loop which at each step removes a -% character from the base signature and leaves one from the variant -% form behind it in a \cs{cs:w} \ldots{} \cs{cs_end:} construction. -% This \texttt{c}-type expansion is not done using \cs{exp_args:NNc} -% because some error-reporting mechanism must escape out of this -% construction. +% |cV| variant form, we want the new signature to be |cVn|. +% +% There are further subtleties: +% \begin{itemize} +% \item In \cs{cs_generate_variant:Nn} |\foo:nnTF| |{xxTF}|, it +% would be better to define |\foo:xxTF| using |\exp_args:Nxx|, +% rather than a hypothetical |\exp_args:NxxTF|. Thus, we wish to +% trim a common trailing part from the base signature and the +% variant signature. +% \item In \cs{cs_generate_variant:Nn} |\foo:on| |{ox}|, the +% function |\foo:ox| should be defined using |\exp_args:Nnx|, not +% |\exp_args:Nox|, to avoid double |o| expansion. +% \item Lastly, \cs{cs_generate_variant:Nn} |\foo:on| |{xn}| should +% trigger an error, because we do not have a means to replace +% |o|-expansion by |x|-expansion. +% \end{itemize} +% All this boils down to a few rules. Only |n| and |N|-type +% arguments can be replaced by \cs{cs_generate_variant:Nn}. Other +% argument types are allowed to be passed unchanged from the base +% form to the variant: in the process they are changed to |n| +% (except for two cases: |N| and |p|-type arguments). A common +% trailing part is ignored. +% +% We compare the base and variant signatures one character at a time +% within |x|-expansion. The result is given to +% \cs{@@_generate_variant:wwNN} in the form \meta{processed variant +% signature} \cs{q_mark} \meta{errors} \cs{q_stop} \meta{base +% function} \meta{new function}. If all went well, \meta{errors} +% is empty; otherwise, it is a kernel error message, followed by +% some clean-up code (\cs{use_none:nnnn}). +% +% Note the space after |#3| and after the following brace group. +% Those are ignored by \TeX{} when fetching the last argument for +% \cs{@@_generate_variant_loop:nNwN}, but can be used as a delimiter +% for \cs{@@_generate_variant_loop_end:nwwwNNnn}. % \begin{macrocode} \cs_new_protected:Npn \@@_generate_variant:Nnnw #1#2#3#4 , { - \if:w ? #4 + \if_meaning:w \scan_stop: #4 \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: - \exp_after:wN \@@_generate_variant:NNn - \exp_after:wN #1 - \cs:w - #2 : - \@@_generate_variant_loop:NwN - ? #3 - \q_mark #4 \@@_generate_variant_loop_end:w - \q_mark \@@_generate_variant_loop_error:wnNNnn - \q_stop - \cs_end: - {#4} + \use:x + { + \exp_not:N \@@_generate_variant:wwNN + \@@_generate_variant_loop:nNwN { } + #4 + \@@_generate_variant_loop_end:nwwwNNnn + \q_mark + #3 ~ + { ~ { } \fi: \@@_generate_variant_loop_long:wNNnn } ~ + { } + \q_stop + \exp_not:N #1 {#2} {#4} + } \@@_generate_variant:Nnnw #1 {#2} {#3} } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_generate_variant_loop:NwN} % \begin{macro}[aux, EXP] % { -% \@@_generate_variant_loop_end:w, -% \@@_generate_variant_loop_error:wnNNnn +% \@@_generate_variant_loop:nNwN, +% \@@_generate_variant_loop_same:w, +% \@@_generate_variant_loop_end:nwwwNNnn, +% \@@_generate_variant_loop_long:wNNnn, +% \@@_generate_variant_loop_invalid:NNwNNnn, % } -% Normally, the loop takes one character of the base signature and one -% from the variant form (after \cs{q_mark}), and leaves the latter one -% in the input stream. This stops when |#3| is the \texttt{loop_end} -% auxiliary, which, once left in the input stream, cleans up the rest -% of the csname construction. In case the base signature was in fact -% shorter, one reaches the point where |#1| is the \cs{q_mark} which -% is supposed to separate the base signature from the variant form. -% Then |#2| is delimited by the next \cs{q_mark}, and the -% \texttt{loop_error} auxiliary is taken as |#3|. This function -% fetches appropriate arguments for an error message, and places it -% outside the csname construction. -% -% Note in the definition of \cs{@@_generate_variant:Nnnw} the base -% signature is preceeded by a question mark. This shifts the base -% signature and variant form to compensate for the presence of the -% \texttt{loop_end} auxiliary at the end of the variant form. +% \begin{arguments} +% \item Last few (consecutive) letters common between the base +% and variant (in fact, \cs{@@_generate_variant_same:N} +% \meta{letter} for each letter). +% \item Next variant letter. +% \item Remainder of variant form. +% \item Next base letter. +% \end{arguments} +% The first argument is populated by +% \cs{@@_generate_variant_loop_same:w} when a variant letter and a +% base letter match. It is flushed into the input stream whenever the +% two letters are different: if the loop ends before, the argument is +% dropped, which means that trailing common letters are ignored. +% +% The case where the two letters are different is only allowed with a +% base letter of |N| or |n|. Otherwise, call +% \cs{@@_generate_variant_loop_invalid:NNwNNnn} to remove the end of +% the loop, get arguments at the end of the loop, and place an +% appropriate error message as a second argument of +% \cs{@@_generate_variant:wwNN}. If the letters are distinct and +% the base letter is indeed |n| or |N|, leave in the input stream +% whatever argument was collected, and the next variant letter |#2|, +% then loop by calling \cs{@@_generate_variant_loop:nNwN}. +% +% The loop can stop in three ways. +% \begin{itemize} +% \item If the end of the variant form is encountered first, |#2| is +% \cs{@@_generate_variant_loop_end:nwwwNNnn} (expanded by the +% conditional \cs{if:w}), which inserts some tokens to end the +% conditional; grabs the \meta{base name} as |#7|, the +% \meta{variant signature} |#8|, the \meta{next base letter} |#1| +% and the part |#3| of the base signature that wasn't read yet; +% and combines those into the \meta{new function} to be defined. +% \item If the end of the base form is encountered first, |#4| is +% |~{}\fi:| which ends the conditional (with an empty expansion), +% followed by \cs{@@_generate_variant_loop_long:wNNnn}, which +% places an error as the second argument of +% \cs{@@_generate_variant:wwNN}. +% \item The loop can be interrupted early if the requested expansion +% is unavailable, namely when the variant and base letters differ +% and the base is neither |n| nor |N|. Again, an error is placed +% as the second argument of \cs{@@_generate_variant:wwNN}. +% \end{itemize} +% Note that if the variant form has the same length as the base form, +% |#2| is as described in the first point, and |#4| as described in +% the second point above. The \cs{@@_generate_variant_loop_end:nwwwNNnn} +% breaking function takes the empty brace group in |#4| as its first +% argument: this empty brace group produces the correct signature for +% the full variant. % \begin{macrocode} -\cs_new:Npn \@@_generate_variant_loop:NwN #1 #2 \q_mark #3 - { #3 \@@_generate_variant_loop:NwN #2 \q_mark } -\cs_new:Npn \@@_generate_variant_loop_end:w #1#2 \q_mark #3 \q_stop {#2} -\cs_new:Npn \@@_generate_variant_loop_error:wnNNnn - #1 \q_stop \cs_end: #2 #3#4#5#6 +\cs_new:Npn \@@_generate_variant_loop:nNwN #1#2#3 \q_mark #4 + { + \if:w #2 #4 + \exp_after:wN \@@_generate_variant_loop_same:w + \else: + \if:w N #4 \else: + \if:w n #4 \else: + \@@_generate_variant_loop_invalid:NNwNNnn #4#2 + \fi: + \fi: + \fi: + #1 + \prg_do_nothing: + #2 + \@@_generate_variant_loop:nNwN { } #3 \q_mark + } +\cs_new:Npn \@@_generate_variant_loop_same:w + #1 \prg_do_nothing: #2#3#4 + { + #3 { #1 \@@_generate_variant_same:N #2 } + } +\cs_new:Npn \@@_generate_variant_loop_end:nwwwNNnn + #1#2 \q_mark #3 ~ #4 \q_stop #5#6#7#8 { - \cs_end: {#2} - \__msg_kernel_error:nnxx { kernel } { variant-too-long } - { \tl_to_str:n {#2} } { \token_to_str:N #4 } - #3 #4 {#5} {#6} + \scan_stop: \scan_stop: \fi: + \exp_not:N \q_mark + \exp_not:N \q_stop + \exp_not:N #6 + \exp_not:c { #7 : #8 #1 #3 } + } +\cs_new:Npn \@@_generate_variant_loop_long:wNNnn #1 \q_stop #2#3#4#5 + { + \exp_not:n + { + \q_mark + \__msg_kernel_error:nnxx { kernel } { variant-too-long } + {#5} { \token_to_str:N #3 } + \use_none:nnnn + \q_stop + #3 + #3 + } + } +\cs_new:Npn \@@_generate_variant_loop_invalid:NNwNNnn + #1#2 \fi: \fi: \fi: #3 \q_stop #4#5#6#7 + { + \fi: \fi: \fi: + \exp_not:n + { + \q_mark + \__msg_kernel_error:nnxxxx { kernel } { invalid-variant } + {#7} { \token_to_str:N #5 } {#1} {#2} + \use_none:nnnn + \q_stop + #5 + #5 + } } % \end{macrocode} % \end{macro} +% +% \begin{macro}[aux, rEXP]{\@@_generate_variant_same:N} +% When the base and variant letters are identical, don't do any +% expansion. For most argument types, we can use the |n|-type +% no-expansion, but the |N| and |p| types require a slightly different +% behaviour with respect to braces. +% \begin{macrocode} +\cs_new:Npn \@@_generate_variant_same:N #1 + { + \if:w N #1 + N + \else: + \if:w p #1 + p + \else: + n + \fi: + \fi: + } +% \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\@@_generate_variant:NNn} +% \begin{macro}[aux]{\@@_generate_variant:wwNN} % If the variant form has already been defined, log its existence. % Otherwise, make sure that the |\exp_args:N #3| form is defined, and % if it contains |x|, change \cs{@@_tmp:w} locally to % \cs{cs_new_protected_nopar:Npx}. Then define the variant by % combining the |\exp_args:N #3| variant and the base function. % \begin{macrocode} -\cs_new_protected:Npn \@@_generate_variant:NNn #1 #2 #3 +\cs_new_protected:Npn \@@_generate_variant:wwNN + #1 \q_mark #2 \q_stop #3#4 { - \cs_if_free:NTF #2 + #2 + \cs_if_free:NTF #4 { \group_begin: - \@@_generate_internal_variant:n {#3} - \@@_tmp:w #2 { \exp_not:c { exp_args:N #3 } \exp_not:N #1 } + \@@_generate_internal_variant:n {#1} + \@@_tmp:w #4 { \exp_not:c { exp_args:N #1 } \exp_not:N #3 } \group_end: } { \iow_log:x { - Variant~\token_to_str:N #2~% + Variant~\token_to_str:N #4~% already~defined;~ not~ changing~ it~on~line~% \tex_the:D \tex_inputlineno:D } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index 3816602c541..5011c868715 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3file.dtx 4059 2012-08-08 13:12:06Z bruno $ +\GetIdInfo$Id: l3file.dtx 4101 2012-08-15 16:05:33Z bruno $ {L3 File and I/O operations} %</driver|package> %<*driver> @@ -565,6 +565,14 @@ % \end{macrocode} % \end{variable} % +% \begin{variable}{\l_@@_internal_tl} +% Used as a short-term scratch variable. It may be possible to reuse +% \cs{l_@@_internal_name_tl} there. +% \begin{macrocode} +\tl_new:N \l_@@_internal_tl +% \end{macrocode} +% \end{variable} +% % \begin{variable}{\l_@@_internal_name_tl} % Used to return the fully-qualified name of a file. % \begin{macrocode} @@ -726,10 +734,11 @@ { \@addtofilelist {#1} } { \seq_gput_right:Nn \g_@@_record_seq {#1} } %</package> - \seq_gpush:Nn \g_@@_stack_seq \g_file_current_name_tl + \seq_gpush:No \g_@@_stack_seq \g_file_current_name_tl \tl_gset:Nn \g_file_current_name_tl {#1} \tex_input:D #1 \c_space_tl - \seq_gpop:NN \g_@@_stack_seq \g_file_current_name_tl + \seq_gpop:NN \g_@@_stack_seq \l_@@_internal_tl + \tl_gset_eq:NN \g_file_current_name_tl \l_@@_internal_tl } \cs_generate_variant:Nn \@@_input_aux:n { o } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx index 92307fbacf7..142a3c5afac 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-assign.dtx 4082 2012-08-12 12:14:17Z bruno $ +\GetIdInfo$Id: l3fp-assign.dtx 4129 2012-08-20 20:38:28Z mittelba $ {L3 Floating-point assignments} \documentclass[full]{l3doc} \begin{document} @@ -187,7 +187,14 @@ % form, starting with |>|, and displays the rest. % \begin{macrocode} \cs_new_protected:Npn \fp_show:N #1 - { \__msg_show_variable:x { > \fp_to_tl:N #1 } } + { + \fp_if_exist:NTF #1 + { \__msg_show_variable:x { > \fp_to_tl:N #1 } } + { + \__msg_kernel_error:nnx { kernel } { variable-not-defined } + { \token_to_str:N #1 } + } + } \cs_new_protected:Npn \fp_show:n #1 { \__msg_show_variable:x { > \fp_to_tl:n {#1} } } \cs_generate_variant:Nn \fp_show:N { c } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx index 2a26c63ada5..74bacd5d9d8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-aux.dtx 4089 2012-08-14 04:52:20Z bruno $ +\GetIdInfo$Id: l3fp-aux.dtx 4151 2012-08-28 11:51:52Z bruno $ {L3 Floating-point support functions} \documentclass[full]{l3doc} \begin{document} @@ -210,7 +210,7 @@ % \end{macrocode} % \end{variable} % -% \begin{variable}{\c_@@_max_exponent_int} +% \begin{variable}[int]{\c_@@_max_exponent_int} % Normal floating point numbers have an exponent at most % \texttt{max_exponent} in absolute value. Larger numbers are rounded % to $\pm\infty$. Smaller numbers are subnormal (not implemented yet), @@ -325,7 +325,7 @@ % \cs{exp_after:wN}) or \texttt{f}-expansion, and leaves the floating % point number unchanged. % -% We first distinguish normal floating points, which have a mantissa, +% We first distinguish normal floating points, which have a significand, % from the much simpler special floating points. % \begin{macrocode} \cs_new:Npn \@@_exp_after_o:w \s_@@ \@@_chk:w #1 @@ -464,8 +464,8 @@ % provide different sets of packing functions and shifts, depending on % ranges of input. % -% \begin{macro}[int, EXP]{\@@_pack:NNNNNw} -% \begin{variable} +% \begin{macro}[int, EXP]{\@@_pack:NNNNNw, \@@_pack:NNNNNwn} +% \begin{variable}[int] % { % \c_@@_trailing_shift_int , % \c_@@_middle_shift_int , @@ -473,18 +473,21 @@ % } % This set of shifts allows for computations involving results in the % range $[-4\cdot 10^{8}, 5\cdot 10^{8}-1]$. Shifted values all have -% exactly $9$ digits. +% exactly $9$ digits. The \cs{@@_pack:NNNNNwn} function brings a +% braced \meta{continuation} up through the levels of expansion. % \begin{macrocode} \int_const:Nn \c_@@_leading_shift_int { - 5 0000 } \int_const:Nn \c_@@_middle_shift_int { 5 0000 * 9999 } \int_const:Nn \c_@@_trailing_shift_int { 5 0000 * 10000 } \cs_new:Npn \@@_pack:NNNNNw #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} } +\cs_new:Npn \@@_pack:NNNNNwn #1 #2#3#4#5 #6; #7 + { + #1#2#3#4#5 ; {#7} {#6} } % \end{macrocode} % \end{variable} % \end{macro} % -% \begin{macro}[int, EXP]{\@@_pack_big:NNNNNNw} -% \begin{variable} +% \begin{macro}[int, EXP]{\@@_pack_big:NNNNNNw, \@@_pack_big:NNNNNNwn} +% \begin{variable}[int] % { % \c_@@_big_trailing_shift_int , % \c_@@_big_middle_shift_int , @@ -502,12 +505,14 @@ \int_const:Nn \c_@@_big_trailing_shift_int { 15 2374 * 10000 } \cs_new:Npn \@@_pack_big:NNNNNNw #1#2 #3#4#5#6 #7; { + #1#2#3#4#5#6 ; {#7} } +\cs_new:Npn \@@_pack_big:NNNNNNwn #1#2 #3#4#5#6 #7; #8 + { + #1#2#3#4#5#6 ; {#8} {#7} } % \end{macrocode} % \end{variable} % \end{macro} % % \begin{macro}[int, EXP]{\@@_pack_Bigg:NNNNNNw} -% \begin{variable} +% \begin{variable}[int] % { % \c_@@_Bigg_trailing_shift_int , % \c_@@_Bigg_middle_shift_int , diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx index 591ccf5615e..22c72c7b482 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-basics.dtx 4089 2012-08-14 04:52:20Z bruno $ +\GetIdInfo$Id: l3fp-basics.dtx 4151 2012-08-28 11:51:52Z bruno $ {L3 Floating-point arithmetic} \documentclass[full]{l3doc} \begin{document} @@ -97,7 +97,7 @@ % \@@_basics_pack_high:NNNNNw, % \@@_basics_pack_high_carry:w % } -% Addition and multiplication of mantissas are done in two steps: +% Addition and multiplication of significands are done in two steps: % first compute a (more or less) exact result, then round and pack % digits in the final (braced) form. These functions take care of the % packing, with special attention given to the case where rounding has @@ -166,8 +166,8 @@ % detect an invalid operation in the case of $\infty - \infty$; % \item for normal floating point numbers, compare the signs; % \item to add two floating point numbers of the same sign or of -% opposite signs, shift the mantissa of the smaller one to match the -% bigger one, perform the addition or subtraction of mantissas, +% opposite signs, shift the significand of the smaller one to match the +% bigger one, perform the addition or subtraction of significands, % check for a carry, round, and pack using the % |\__fp_basics_pack_...| functions. % \end{itemize} @@ -332,7 +332,7 @@ % the result, and the \meta{final sign} are then given to % \cs{@@_sanitize:Nw} which checks for overflow. The exponent is % computed as the largest exponent |#2| or |#5|, incremented if there -% is a carry. To add the mantissas, we decimate the smaller number by +% is a carry. To add the significands, we decimate the smaller number by % the difference between the exponents. This is done by % \cs{@@_add_big_i:wNww} or \cs{@@_add_big_ii:wNww}. We need to bring % the final sign with us in the midst of the calculation to round @@ -361,13 +361,13 @@ % \cs{@@_add_big_i_o:wNww} \meta{shift} |;| \meta{final sign} % \meta{body_1} |;| \meta{body_2} |;| % \end{quote} -% Shift the mantissa of the small number, then add with -% \cs{@@_add_mantissa_o:NnnwnnnnN}. +% Shift the significand of the small number, then add with +% \cs{@@_add_significand_o:NnnwnnnnN}. % \begin{macrocode} \cs_new:Npn \@@_add_big_i_o:wNww #1; #2 #3; #4; { \@@_decimate:nNnnnn {#1} - \@@_add_mantissa_o:NnnwnnnnN + \@@_add_significand_o:NnnwnnnnN #4 #3 #2 @@ -375,7 +375,7 @@ \cs_new:Npn \@@_add_big_ii_o:wNww #1; #2 #3; #4; { \@@_decimate:nNnnnn {#1} - \@@_add_mantissa_o:NnnwnnnnN + \@@_add_significand_o:NnnwnnnnN #3 #4 #2 @@ -384,11 +384,11 @@ % \end{macro} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_add_mantissa_o:NnnwnnnnN} +% \begin{macro}[aux, rEXP]{\@@_add_significand_o:NnnwnnnnN} % \begin{macro}[aux, rEXP] -% {\@@_add_mantissa_pack:NNNNNNN, \@@_add_mantissa_test_o:N} +% {\@@_add_significand_pack:NNNNNNN, \@@_add_significand_test_o:N} % \begin{quote} -% \cs{@@_add_mantissa_o:NnnwnnnnN} +% \cs{@@_add_significand_o:NnnwnnnnN} % \meta{rounding digit} % \Arg{Y'_1} \Arg{Y'_2} \meta{extra-digits} |;| % \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} @@ -403,35 +403,35 @@ % give an exact power of $10$, for which it is easy to correct % the result at the end. % \begin{macrocode} -\cs_new:Npn \@@_add_mantissa_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8 +\cs_new:Npn \@@_add_significand_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8 { - \exp_after:wN \@@_add_mantissa_test_o:N + \exp_after:wN \@@_add_significand_test_o:N \int_use:N \__int_eval:w 1#5#6 + #2 - \exp_after:wN \@@_add_mantissa_pack:NNNNNNN + \exp_after:wN \@@_add_significand_pack:NNNNNNN \int_use:N \__int_eval:w 1#7#8 + #3 ; #1 } -\cs_new:Npn \@@_add_mantissa_pack:NNNNNNN #1 #2#3#4#5#6#7 +\cs_new:Npn \@@_add_significand_pack:NNNNNNN #1 #2#3#4#5#6#7 { \if_meaning:w 2 #1 + \c_one \fi: ; #2 #3 #4 #5 #6 #7 ; } -\cs_new:Npn \@@_add_mantissa_test_o:N #1 +\cs_new:Npn \@@_add_significand_test_o:N #1 { \if_meaning:w 2 #1 - \exp_after:wN \@@_add_mantissa_carry_o:wwwNN + \exp_after:wN \@@_add_significand_carry_o:wwwNN \else: - \exp_after:wN \@@_add_mantissa_no_carry_o:wwwNN + \exp_after:wN \@@_add_significand_no_carry_o:wwwNN \fi: } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_add_mantissa_no_carry_o:wwwNN} +% \begin{macro}[aux, rEXP]{\@@_add_significand_no_carry_o:wwwNN} % \begin{quote} -% \cs{@@_add_mantissa_no_carry_o:wwwNN} +% \cs{@@_add_significand_no_carry_o:wwwNN} % \meta{8d} |;| \meta{6d} |;| \meta{2d} |;| % \meta{rounding digit} \meta{sign} % \end{quote} @@ -439,7 +439,7 @@ % packing function \cs{@@_basics_pack_high:NNNNNw} takes care of the % case where rounding brings a carry. % \begin{macrocode} -\cs_new:Npn \@@_add_mantissa_no_carry_o:wwwNN +\cs_new:Npn \@@_add_significand_no_carry_o:wwwNN #1; #2; #3#4 ; #5#6 { \exp_after:wN \@@_basics_pack_high:NNNNNw @@ -452,16 +452,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_add_mantissa_carry_o:wwwNN} +% \begin{macro}[aux, rEXP]{\@@_add_significand_carry_o:wwwNN} % \begin{quote} -% \cs{@@_add_mantissa_carry_o:wwwNN} +% \cs{@@_add_significand_carry_o:wwwNN} % \meta{8d} |;| \meta{6d} |;| \meta{2d} |;| % \meta{rounding digit} \meta{sign} % \end{quote} % The case where there is a carry is very similar. Rounding can even % raise the first digit from $1$ to $2$, but we don't care. % \begin{macrocode} -\cs_new:Npn \@@_add_mantissa_carry_o:wwwNN +\cs_new:Npn \@@_add_significand_carry_o:wwwNN #1; #2; #3#4; #5#6 { + \c_one @@ -490,7 +490,7 @@ % \end{quote} % Rounding properly in some modes requires to know what the sign of % the result will be. Thus, we start by comparing the exponents and -% mantissas. If the numbers coincide, return zero. If the second +% significands. If the numbers coincide, return zero. If the second % number is larger, swap the numbers and call % \cs{@@_sub_npos_i_o:Nnwnw} with the opposite of \meta{sign_1}. % \begin{macrocode} @@ -524,7 +524,7 @@ % and may be decreased if the two numbers are very close. If the two % numbers have the same exponent, call the \texttt{near} auxiliary. % Otherwise, decimate $y$, then call the \texttt{far} auxiliary to -% evaluate the difference between the two mantissas. Note that we +% evaluate the difference between the two significands. Note that we % decimate by $1$ less than one could expect. % \begin{macrocode} \cs_new:Npn \@@_sub_npos_i_o:Nnwnw #1 #2#3; #4#5; @@ -650,7 +650,7 @@ % and semi-colon delimiters to allow the \texttt{not_far} auxiliary to % grab each piece individually, the \texttt{very_far} auxiliary to use % \cs{@@_pack_eight:wNNNNNNNN}, and the \texttt{quite_far} to ignore -% the mantissas easily (using the |;| delimiter). +% the significands easily (using the |;| delimiter). % \begin{macrocode} \cs_new:Npn \@@_sub_back_far_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8 { @@ -738,7 +738,7 @@ % \begin{macro}[aux, EXP]{\@@_sub_back_very_far_ii_o:nnNwwNN} % The case where $x-y$ and $x$ have the same exponent is a bit more % tricky, mostly because it cannot reuse the same auxiliaries. Shift -% the $y$~mantissa by adding a leading~$0$. Then the logic is similar +% the $y$~significand by adding a leading~$0$. Then the logic is similar % to the \texttt{not_far} functions above. Rounding is a bit more % complicated: we have two \meta{rounding} digits |#3| and |#6| (from % the decimation, and from the new shift) to take into account, and @@ -869,9 +869,9 @@ % After the computation, \cs{@@_sanitize:Nw} checks for overflow or % underflow. As we did for addition, \cs{__int_eval:w} computes the % exponent, catching any shift coming from the computation in the -% mantissa. The \meta{final sign} is needed to do the rounding -% properly in the mantissa computation. We setup the post-expansion -% here, triggered by \cs{@@_mul_mantissa_o:nnnnNnnnn}. +% significand. The \meta{final sign} is needed to do the rounding +% properly in the significand computation. We setup the post-expansion +% here, triggered by \cs{@@_mul_significand_o:nnnnNnnnn}. % \begin{macrocode} \cs_new:Npn \@@_mul_npos_o:Nww #1 \s_@@ \@@_chk:w #2 #3 #4 #5 ; \s_@@ \@@_chk:w #6 #7 #8 #9 ; @@ -880,21 +880,21 @@ \exp_after:wN #1 \int_use:N \__int_eval:w #4 + #8 - \@@_mul_mantissa_o:nnnnNnnnn #5 #1 #9 + \@@_mul_significand_o:nnnnNnnnn #5 #1 #9 } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_mul_mantissa_o:nnnnNnnnn} +% \begin{macro}[aux, rEXP]{\@@_mul_significand_o:nnnnNnnnn} % \begin{macro}[aux, EXP] -% {\@@_mul_mantissa_drop:NNNNNw, \@@_mul_mantissa_keep:NNNNNw} +% {\@@_mul_significand_drop:NNNNNw, \@@_mul_significand_keep:NNNNNw} % \begin{quote} -% \cs{@@_mul_mantissa_o:nnnnNnnnn} +% \cs{@@_mul_significand_o:nnnnNnnnn} % \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \meta{sign} % \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4} % \end{quote} % Note the three semicolons at the end of the definition. One is for -% the last \cs{@@_mul_mantissa_drop:NNNNNw}; one is for +% the last \cs{@@_mul_significand_drop:NNNNNw}; one is for % \cs{@@_round_digit:Nw} later on; and one, preceeded by % \cs{exp_after:wN}, which is correctly expanded (within an % \cs{__int_eval:w}), is used by \cs{@@_basics_pack_low:NNNNNw}. @@ -909,36 +909,36 @@ % known, and we can do the rounding within yet another set of % \cs{__int_eval:w}. % \begin{macrocode} -\cs_new:Npn \@@_mul_mantissa_o:nnnnNnnnn #1#2#3#4 #5 #6#7#8#9 +\cs_new:Npn \@@_mul_significand_o:nnnnNnnnn #1#2#3#4 #5 #6#7#8#9 { - \exp_after:wN \@@_mul_mantissa_test_f:NNN + \exp_after:wN \@@_mul_significand_test_f:NNN \exp_after:wN #5 \int_use:N \__int_eval:w 99990000 + #1*#6 + - \exp_after:wN \@@_mul_mantissa_keep:NNNNNw + \exp_after:wN \@@_mul_significand_keep:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#7 + #2*#6 + - \exp_after:wN \@@_mul_mantissa_keep:NNNNNw + \exp_after:wN \@@_mul_significand_keep:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#8 + #2*#7 + #3*#6 + - \exp_after:wN \@@_mul_mantissa_drop:NNNNNw + \exp_after:wN \@@_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#9 + #2*#8 + #3*#7 + #4*#6 + - \exp_after:wN \@@_mul_mantissa_drop:NNNNNw + \exp_after:wN \@@_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #2*#9 + #3*#8 + #4*#7 + - \exp_after:wN \@@_mul_mantissa_drop:NNNNNw + \exp_after:wN \@@_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #3*#9 + #4*#8 + - \exp_after:wN \@@_mul_mantissa_drop:NNNNNw + \exp_after:wN \@@_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 100000000 + #4*#9 ; ; \exp_after:wN ; } -\cs_new:Npn \@@_mul_mantissa_drop:NNNNNw #1#2#3#4#5 #6; +\cs_new:Npn \@@_mul_significand_drop:NNNNNw #1#2#3#4#5 #6; { #1#2#3#4#5 ; + #6 } -\cs_new:Npn \@@_mul_mantissa_keep:NNNNNw #1#2#3#4#5 #6; +\cs_new:Npn \@@_mul_significand_keep:NNNNNw #1#2#3#4#5 #6; { #1#2#3#4#5 ; #6 ; } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_mul_mantissa_test_f:NNN} +% \begin{macro}[aux, rEXP]{\@@_mul_significand_test_f:NNN} % \begin{quote} -% \cs{@@_mul_mantissa_test_f:NNN} \meta{sign} |1| +% \cs{@@_mul_significand_test_f:NNN} \meta{sign} |1| % \meta{digits 1--8} |;| \meta{digits 9--12} |;| \meta{digits 13--16} |;| % |+| \meta{digits 17--20} |+| \meta{digits 21--24} % |+| \meta{digits 25--28} |+| \meta{digits 29--32} |;| @@ -950,19 +950,19 @@ % is zero, we care about digits $17$ and $18$, and whether further % digits are zero. % \begin{macrocode} -\cs_new:Npn \@@_mul_mantissa_test_f:NNN #1 #2 #3 +\cs_new:Npn \@@_mul_significand_test_f:NNN #1 #2 #3 { \if_meaning:w 0 #3 - \exp_after:wN \@@_mul_mantissa_small_f:NNwwwN + \exp_after:wN \@@_mul_significand_small_f:NNwwwN \else: - \exp_after:wN \@@_mul_mantissa_large_f:NwwNNNN + \exp_after:wN \@@_mul_significand_large_f:NwwNNNN \fi: #1 #3 } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_mul_mantissa_large_f:NwwNNNN} +% \begin{macro}[aux, EXP]{\@@_mul_significand_large_f:NwwNNNN} % In this branch, \meta{digit 1} is non-zero. The result is thus % \meta{digits 1--16}, plus some rounding which depends on the digits % $16$, $17$, and whether all subsequent digits are zero or not. @@ -970,7 +970,7 @@ % integer expression), and replaces it by a \meta{rounding digit}, % suitable for \cs{@@_round:NNN}. % \begin{macrocode} -\cs_new:Npn \@@_mul_mantissa_large_f:NwwNNNN #1 #2; #3; #4#5#6#7; + +\cs_new:Npn \@@_mul_significand_large_f:NwwNNNN #1 #2; #3; #4#5#6#7; + { \exp_after:wN \@@_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1#2 @@ -984,7 +984,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_mul_mantissa_small_f:NNwwwN} +% \begin{macro}[aux, rEXP]{\@@_mul_significand_small_f:NNwwwN} % In this branch, \meta{digit 1} is zero. Our result will thus be % \meta{digits 2--17}, plus some rounding which depends on the digits % $17$, $18$, and whether all subsequent digits are zero or not. @@ -992,7 +992,7 @@ % \texttt{small_pack} auxiliary, by the next digit, to form a $9$ % digit number. % \begin{macrocode} -\cs_new:Npn \@@_mul_mantissa_small_f:NNwwwN #1 #2#3; #4#5; #6; + #7 +\cs_new:Npn \@@_mul_significand_small_f:NNwwwN #1 #2#3; #4#5; #6; + #7 { - \c_one \exp_after:wN \@@_basics_pack_high:NNNNNw @@ -1056,7 +1056,7 @@ % \cs{@@_sanitize:Nw} checks for overflow or underflow; we provide it % with the \meta{final sign}, and an integer expression in which we % compute the exponent. We set up the arguments of -% \cs{@@_div_mantissa_i_o:wnnw}, namely an integer \meta{y} obtained +% \cs{@@_div_significand_i_o:wnnw}, namely an integer \meta{y} obtained % by adding $1$ to the first $5$ digits of $Z$ (explanation given soon % below), then the four \Arg{A_{i}}, then the four \Arg{Z_{i}}, a % semi-colon, and the \meta{final sign}, used for rounding at the end. @@ -1068,7 +1068,7 @@ \exp_after:wN #1 \int_use:N \__int_eval:w #3 - #6 - \exp_after:wN \@@_div_mantissa_i_o:wnnw + \exp_after:wN \@@_div_significand_i_o:wnnw \int_use:N \__int_eval:w #7 \use_i:nnnn #8 + \c_one ; #4 {#7}{#8}#9 ; @@ -1246,46 +1246,46 @@ % In each case, we know how to round to an integer, depending on the % parity of $P$, and the rounding mode. % -% \subsubsection{Implementing the mantissa division} +% \subsubsection{Implementing the significand division} % -% \begin{macro}[aux, rEXP]{\@@_div_mantissa_i_o:wnnw} +% \begin{macro}[aux, rEXP]{\@@_div_significand_i_o:wnnw} % \begin{quote} -% \cs{@@_div_mantissa_i_o:wnnw} \meta{y} |;| +% \cs{@@_div_significand_i_o:wnnw} \meta{y} |;| % \Arg{A_1} \Arg{A_2} \Arg{A_3} \Arg{A_4} % \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} |;| \meta{sign} % \end{quote} % Compute $10^{6} + Q_{A}$ (a $7$~digit number thanks to the shift), % unbrace \meta{A_1} and \meta{A_2}, and prepare the % \meta{continuation} arguments for $4$ consecutive calls to -% \cs{@@_div_mantissa_calc:wwnnnnnnn}. Each of these calls will need +% \cs{@@_div_significand_calc:wwnnnnnnn}. Each of these calls will need % \meta{y} (|#1|), and it turns out that we need post-expansion there, % hence the \cs{__int_value:w}. Here, |#4| is six brace groups, which % give the six first |n|-type arguments of the \texttt{calc} function. % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_i_o:wnnw #1 ; #2#3 #4 ; +\cs_new:Npn \@@_div_significand_i_o:wnnw #1 ; #2#3 #4 ; { - \exp_after:wN \@@_div_mantissa_test_o:w + \exp_after:wN \@@_div_significand_test_o:w \int_use:N \__int_eval:w - \exp_after:wN \@@_div_mantissa_calc:wwnnnnnnn + \exp_after:wN \@@_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; #4 - { \exp_after:wN \@@_div_mantissa_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_div_mantissa_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_div_mantissa_ii:wwn \__int_value:w #1 } - { \exp_after:wN \@@_div_mantissa_iii:wwnnnnn \__int_value:w #1 } + { \exp_after:wN \@@_div_significand_ii:wwn \__int_value:w #1 } + { \exp_after:wN \@@_div_significand_ii:wwn \__int_value:w #1 } + { \exp_after:wN \@@_div_significand_ii:wwn \__int_value:w #1 } + { \exp_after:wN \@@_div_significand_iii:wwnnnnn \__int_value:w #1 } } % \end{macrocode} % \end{macro} % -% \begin{macro}[int, rEXP]{\@@_div_mantissa_calc:wwnnnnnnn} +% \begin{macro}[int, rEXP]{\@@_div_significand_calc:wwnnnnnnn} % \begin{macro}[aux, rEXP] % { -% \@@_div_mantissa_calc_i:wwnnnnnnn, -% \@@_div_mantissa_calc_ii:wwnnnnnnn, +% \@@_div_significand_calc_i:wwnnnnnnn, +% \@@_div_significand_calc_ii:wwnnnnnnn, % } % \begin{quote} -% \cs{@@_div_mantissa_calc:wwnnnnnnn} \meta{$10^{6}+{}$Q_{A}} |;| +% \cs{@@_div_significand_calc:wwnnnnnnn} \meta{$10^{6}+{}$Q_{A}} |;| % \meta{A_1} \meta{A_2} |;| \Arg{A_3} \Arg{A_4} % \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} % \Arg{continuation} @@ -1337,15 +1337,15 @@ % which produces totals in the range $[10^{9}, 2.1\cdot 10^{9}]$. We % are flirting with \TeX{}'s limits once more. % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_calc:wwnnnnnnn 1#1 +\cs_new:Npn \@@_div_significand_calc:wwnnnnnnn 1#1 { \if_meaning:w 1 #1 - \exp_after:wN \@@_div_mantissa_calc_i:wwnnnnnnn + \exp_after:wN \@@_div_significand_calc_i:wwnnnnnnn \else: - \exp_after:wN \@@_div_mantissa_calc_ii:wwnnnnnnn + \exp_after:wN \@@_div_significand_calc_ii:wwnnnnnnn \fi: } -\cs_new:Npn \@@_div_mantissa_calc_i:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 +\cs_new:Npn \@@_div_significand_calc_i:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 { 1 1 #1 #9 \exp_after:wN ; @@ -1362,7 +1362,7 @@ - #1 * #8 ; {#5}{#6}{#7}{#8} } -\cs_new:Npn \@@_div_mantissa_calc_ii:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 +\cs_new:Npn \@@_div_significand_calc_ii:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 { 1 0 #1 #9 \exp_after:wN ; @@ -1383,9 +1383,9 @@ % \end{macro} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_div_mantissa_ii:wwn} +% \begin{macro}[aux, EXP]{\@@_div_significand_ii:wwn} % \begin{quote} -% \cs{@@_div_mantissa_ii:wwn} \meta{y} |;| +% \cs{@@_div_significand_ii:wwn} \meta{y} |;| % \meta{B_1} |;| \Arg{B_2} \Arg{B_3} \Arg{B_4} % \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} % \meta{continuations} \meta{sign} @@ -1399,19 +1399,19 @@ % auxiliary is also used to compute $Q_{C}$ and $Q_{D}$ with the % inputs $C$ and $D$ instead of $B$. % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_ii:wwn #1; #2;#3 +\cs_new:Npn \@@_div_significand_ii:wwn #1; #2;#3 { - \exp_after:wN \@@_div_mantissa_pack:NNN + \exp_after:wN \@@_div_significand_pack:NNN \int_use:N \__int_eval:w - \exp_after:wN \@@_div_mantissa_calc:wwnnnnnnn + \exp_after:wN \@@_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_div_mantissa_iii:wwnnnnn} +% \begin{macro}[aux, rEXP]{\@@_div_significand_iii:wwnnnnn} % \begin{quote} -% \cs{@@_div_mantissa_iii:wwnnnnn} \meta{y} |;| +% \cs{@@_div_significand_iii:wwnnnnn} \meta{y} |;| % \meta{E_1} |;| \Arg{E_2} \Arg{E_3} \Arg{E_4} % \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \meta{sign} % \end{quote} @@ -1420,10 +1420,10 @@ % add (roughly) $5\cdot P$, which amounts to adding $P/2 \simeq E/Z$ % to $Q_{D}$, the appropriate correction from a hypothetical $Q_{E}$. % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_iii:wwnnnnn #1; #2;#3#4#5 #6#7 +\cs_new:Npn \@@_div_significand_iii:wwnnnnn #1; #2;#3#4#5 #6#7 { 0 - \exp_after:wN \@@_div_mantissa_iv:wwnnnnnnn + \exp_after:wN \@@_div_significand_iv:wwnnnnnnn \int_use:N \__int_eval:w (\c_two * #2 #3) / #6 #7 ; % <- P #2 ; {#3} {#4} {#5} {#6} {#7} @@ -1433,12 +1433,12 @@ % % \begin{macro}[aux, rEXP] % { -% \@@_div_mantissa_iv:wwnnnnnnn, -% \@@_div_mantissa_v:NNw, -% \@@_div_mantissa_vi:Nw +% \@@_div_significand_iv:wwnnnnnnn, +% \@@_div_significand_v:NNw, +% \@@_div_significand_vi:Nw % } % \begin{quote} -% \cs{@@_div_mantissa_iv:wwnnnnnnn} \meta{P} |;| +% \cs{@@_div_significand_iv:wwnnnnnnn} \meta{P} |;| % \meta{E_1} |;| \Arg{E_2} \Arg{E_3} \Arg{E_4} % \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \meta{sign} % \end{quote} @@ -1476,21 +1476,21 @@ % expressions explicitly). $T$ is negative if the first character is % |-|, it is positive if the first character is neither |0| nor |-|. % It is also positive if the first character is |0| and second -% argument of \cs{@@_div_mantissa_vi:Nw}, a sum of several terms, is +% argument of \cs{@@_div_significand_vi:Nw}, a sum of several terms, is % also zero. Otherwise, there was an exact agreement: $T = 0$. % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_iv:wwnnnnnnn #1; #2;#3#4#5 #6#7#8#9 +\cs_new:Npn \@@_div_significand_iv:wwnnnnnnn #1; #2;#3#4#5 #6#7#8#9 { + \c_five * #1 - \exp_after:wN \@@_div_mantissa_vi:Nw + \exp_after:wN \@@_div_significand_vi:Nw \int_use:N \__int_eval:w -20 + 2*#2#3 - #1*#6#7 + - \exp_after:wN \@@_div_mantissa_v:NN + \exp_after:wN \@@_div_significand_v:NN \int_use:N \__int_eval:w 199980 + 2*#4 - #1*#8 + - \exp_after:wN \@@_div_mantissa_v:NN + \exp_after:wN \@@_div_significand_v:NN \int_use:N \__int_eval:w 200000 + 2*#5 - #1*#9 ; } -\cs_new:Npn \@@_div_mantissa_v:NN #1#2 { #1#2 \__int_eval_end: + } -\cs_new:Npn \@@_div_mantissa_vi:Nw #1#2; +\cs_new:Npn \@@_div_significand_v:NN #1#2 { #1#2 \__int_eval_end: + } +\cs_new:Npn \@@_div_significand_vi:Nw #1#2; { \if_meaning:w 0 #1 \if_int_compare:w \__int_eval:w #2 > \c_zero + \c_one \fi: @@ -1502,15 +1502,15 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_div_mantissa_pack:NNN} +% \begin{macro}[aux, EXP]{\@@_div_significand_pack:NNN} % At this stage, we are in the following situation: \TeX{} is in the % process of expanding several integer expressions, thus functions at % the bottom expand before those above. % \begin{quote} -% \cs{@@_div_mantissa_test_o:w} $10^{6} + Q_{A}$ -% \cs{@@_div_mantissa_pack:NNN} $10^{6} + Q_{B}$ -% \cs{@@_div_mantissa_pack:NNN} $10^{6} + Q_{C}$ -% \cs{@@_div_mantissa_pack:NNN} +% \cs{@@_div_significand_test_o:w} $10^{6} + Q_{A}$ +% \cs{@@_div_significand_pack:NNN} $10^{6} + Q_{B}$ +% \cs{@@_div_significand_pack:NNN} $10^{6} + Q_{C}$ +% \cs{@@_div_significand_pack:NNN} % $10^{7} + 10\cdot Q_{D} + 5 \cdot P + \varepsilon$ |;| \meta{sign} % \end{quote} % Here, $\varepsilon = \operatorname{sign}(T)$ is $0$ in case $2E=PZ$, @@ -1520,13 +1520,13 @@ % nothing special: it removes the $10^{6}$ and carries two digits (for % the $10^{5}$'s and the $10^{4}$'s). % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_pack:NNN 1 #1 #2 { + #1 #2 ; } +\cs_new:Npn \@@_div_significand_pack:NNN 1 #1 #2 { + #1 #2 ; } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_div_mantissa_test_o:w} +% \begin{macro}[aux, rEXP]{\@@_div_significand_test_o:w} % \begin{quote} -% \cs{@@_div_mantissa_test_o:w} |1| |0| \meta{5d} |;| +% \cs{@@_div_significand_test_o:w} |1| |0| \meta{5d} |;| % ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{sign} % \end{quote} % The reason we know that the first two digits are |1| and |0| is that @@ -1538,28 +1538,28 @@ % It is now time to round. This depends on how many digits the final % result will have. % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_test_o:w 10 #1 +\cs_new:Npn \@@_div_significand_test_o:w 10 #1 { \if_meaning:w 0 #1 - \exp_after:wN \@@_div_mantissa_small_o:wwwNNNNwN + \exp_after:wN \@@_div_significand_small_o:wwwNNNNwN \else: - \exp_after:wN \@@_div_mantissa_large_o:wwwNNNNwN + \exp_after:wN \@@_div_significand_large_o:wwwNNNNwN \fi: #1 } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_div_mantissa_small_o:wwwNNNNwN} +% \begin{macro}[aux, EXP]{\@@_div_significand_small_o:wwwNNNNwN} % \begin{quote} -% \cs{@@_div_mantissa_small_o:wwwNNNNwN} |0| \meta{4d} |;| +% \cs{@@_div_significand_small_o:wwwNNNNwN} |0| \meta{4d} |;| % ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{final sign} % \end{quote} % Standard use of \cs{@@_basics_pack_low:NNNNNw} and % \cs{@@_basics_pack_high:NNNNNw}. We finally get to use the % \meta{final sign} which has been sitting there for a while. % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_small_o:wwwNNNNwN +\cs_new:Npn \@@_div_significand_small_o:wwwNNNNwN 0 #1; #2; #3; #4#5#6#7#8; #9 { \exp_after:wN \@@_basics_pack_high:NNNNNw @@ -1572,9 +1572,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, rEXP]{\@@_div_mantissa_large_o:wwwNNNNwN} +% \begin{macro}[aux, rEXP]{\@@_div_significand_large_o:wwwNNNNwN} % \begin{quote} -% \cs{@@_div_mantissa_large_o:wwwNNNNwN} \meta{5d} |;| +% \cs{@@_div_significand_large_o:wwwNNNNwN} \meta{5d} |;| % ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{sign} % \end{quote} % We know that the final result cannot reach $10$, hence |1#1#2|, @@ -1582,7 +1582,7 @@ % $2\cdot 10^{9}$. For rounding, we build the \meta{rounding digit} % from the last two of our $18$ digits. % \begin{macrocode} -\cs_new:Npn \@@_div_mantissa_large_o:wwwNNNNwN +\cs_new:Npn \@@_div_significand_large_o:wwwNNNNwN #1; #2; #3; #4#5#6#7#8; #9 { + \c_one @@ -1603,15 +1603,17 @@ % % \begin{macro}[int, EXP]{\@@_neg_o:w} % This function flips the sign of the \meta{floating point} and -% expands after it in the input stream, just like \cs{@@_+_o:ww} etc. +% expands after it in the input stream, just like \cs{@@_+_o:ww} +% \emph{etc.} We add a hook used by \pkg{l3fp-expo}: anything before +% \cs{s_@@} is ignored. % \begin{macrocode} -\cs_new:Npn \@@_neg_o:w \s_@@ \@@_chk:w #1 #2 +\cs_new:Npn \@@_neg_o:w #1 \s_@@ \@@_chk:w #2 #3 { \exp_after:wN \@@_exp_after_o:w \exp_after:wN \s_@@ \exp_after:wN \@@_chk:w - \exp_after:wN #1 - \int_use:N \__int_eval:w \c_two - #2 \__int_eval_end: + \exp_after:wN #2 + \int_use:N \__int_eval:w \c_two - #3 \__int_eval_end: } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx index 8f0c2848ea4..0135da6304b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-convert.dtx 4090 2012-08-14 07:57:01Z joseph $ +\GetIdInfo$Id: l3fp-convert.dtx 4129 2012-08-20 20:38:28Z mittelba $ {L3 Floating-point conversion} \documentclass[full]{l3doc} \begin{document} @@ -469,6 +469,31 @@ % \end{macrocode} % \end{macro} % +% \subsection{Convert an array of floating points to a comma list} +% +% \begin{macro}[int, EXP]{\@@_array_to_clist:n} +% \begin{macro}[aux, EXP]{\@@_array_to_clist_i:wwww, \@@_array_to_clist_ii:ww} +% Converts an array of floating point numbers to a comma-list. +% \begin{macrocode} +\cs_new:Npn \@@_array_to_clist:n #1 + { + \@@_array_to_clist_i:wwww ; + #1 + \@@_array_to_clist_ii:ww \s_@@ ; @ + ; , ~ , ~ @ \s_stop + } +\cs_new:Npn \@@_array_to_clist_i:wwww #1; #2 \s_@@ #3; #4 @ + { + #2 + \exp_after:wN \@@_array_to_clist_i:wwww + \tex_romannumeral:D -`0 \@@_to_tl:w \s_@@ #3 ; ; + #4 , ~ #1 @ + } +\cs_new:Npn \@@_array_to_clist_ii:ww #1 ; , ~ , ~ #2 @ #3 \s_stop {#2} +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx index fee1b90ed58..f228794e7a4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-expo.dtx 4089 2012-08-14 04:52:20Z bruno $ +\GetIdInfo$Id: l3fp-expo.dtx 4151 2012-08-28 11:51:52Z bruno $ {L3 Floating-point exponential-related functions} \documentclass[full]{l3doc} \begin{document} @@ -324,7 +324,7 @@ % \begin{macrocode} \cs_new:Npn \@@_ln_x_iv:wnnnnnnnn #1; #2#3#4#5 #6#7#8#9 { - \exp_after:wN \@@_div_mantissa_pack:NNN + \exp_after:wN \@@_div_significand_pack:NNN \int_use:N \__int_eval:w \@@_ln_div_i:w #1 ; #6 #7 ; {#8} {#9} @@ -337,20 +337,20 @@ } \cs_new:Npn \@@_ln_div_i:w #1; { - \exp_after:wN \@@_div_mantissa_calc:wwnnnnnnn + \exp_after:wN \@@_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + 2 0000 0000 / #1 ; % Q1 } \cs_new:Npn \@@_ln_div_ii:wwn #1; #2;#3 % y; B1;B2 <- for k=1 { - \exp_after:wN \@@_div_mantissa_pack:NNN + \exp_after:wN \@@_div_significand_pack:NNN \int_use:N \__int_eval:w - \exp_after:wN \@@_div_mantissa_calc:wwnnnnnnn + \exp_after:wN \@@_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 / #1 ; % Q2 #2 #3 ; } \cs_new:Npn \@@_ln_div_vi:wwn #1; #2;#3#4#5 #6#7#8#9 %y;F1;F2F3F4x1x2x3x4 { - \exp_after:wN \@@_div_mantissa_pack:NNN + \exp_after:wN \@@_div_significand_pack:NNN \int_use:N \__int_eval:w 1000000 + #2 #3 / #1 ; % Q6 } % \end{macrocode} @@ -360,18 +360,18 @@ % result, small enough in all cases.} % \begin{quote} % \cs{@@_ln_div_after:Nw} \meta{fixed tl} -% \cs{@@_div_mantissa_pack:NNN} $10^6 + Q_{1}$ -% \cs{@@_div_mantissa_pack:NNN} $10^6 + Q_{2}$ -% \cs{@@_div_mantissa_pack:NNN} $10^6 + Q_{3}$ -% \cs{@@_div_mantissa_pack:NNN} $10^6 + Q_{4}$ -% \cs{@@_div_mantissa_pack:NNN} $10^6 + Q_{5}$ -% \cs{@@_div_mantissa_pack:NNN} $10^6 + Q_{6}$ |;| +% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{1}$ +% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{2}$ +% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{3}$ +% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{4}$ +% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{5}$ +% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{6}$ |;| % \meta{exponent} |;| \meta{continuation} % \end{quote} % where \meta{fixed tl} holds the logarithm of a number % in $[1,10]$, and \meta{exponent} is % the exponent. Also, the expansion is done backwards. Then -% \cs{@@_div_mantissa_pack:NNN} puts things in the +% \cs{@@_div_significand_pack:NNN} puts things in the % correct order to add the $Q_{i}$ together and put semicolons % between each piece. Once those have been expanded, we get % \begin{quote} @@ -491,7 +491,7 @@ \@@_ln_Taylor_break:w \fi: \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl ; #1; - \@@_fixed_add:wwN #2; + \@@_fixed_add:wwn #2; \@@_fixed_mul:wwn #3; { \exp_after:wN \@@_ln_Taylor_loop:www @@ -499,7 +499,7 @@ } #3; } -\cs_new:Npn \@@_ln_Taylor_break:w \fi: #1 \@@_fixed_add:wwN #2#3; #4 ;; +\cs_new:Npn \@@_ln_Taylor_break:w \fi: #1 \@@_fixed_add:wwn #2#3; #4 ;; { \fi: \exp_after:wN \@@_fixed_mul:wwn @@ -527,9 +527,9 @@ \cs_new:Npn \@@_ln_c:NwNw #1 #2; #3 { \if_meaning:w + #1 - \exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_sub:wwN + \exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_sub:wwn \else: - \exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_add:wwN + \exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_add:wwn \fi: #3 ; #2 ; } @@ -564,11 +564,11 @@ \if_int_compare:w #2 > \c_zero \exp_after:wN \@@_ln_exponent_small:NNww \exp_after:wN 0 - \exp_after:wN \@@_fixed_sub:wwN \__int_value:w + \exp_after:wN \@@_fixed_sub:wwn \__int_value:w \else: \exp_after:wN \@@_ln_exponent_small:NNww \exp_after:wN 2 - \exp_after:wN \@@_fixed_add:wwN \__int_value:w - + \exp_after:wN \@@_fixed_add:wwn \__int_value:w - \fi: \fi: #2; #1; @@ -580,7 +580,7 @@ \cs_new:Npn \@@_ln_exponent_one:ww 1; #1; { \c_zero - \exp_after:wN \@@_fixed_sub:wwN \c_@@_ln_x_fixed_tl ; #1; + \exp_after:wN \@@_fixed_sub:wwn \c_@@_ln_x_fixed_tl ; #1; \@@_fixed_to_float:wN 0 } % \end{macrocode} @@ -673,7 +673,7 @@ } #5 {#4} - #2 0 + #1 #2 0 \tex_romannumeral:D \fi: \fi: @@ -693,8 +693,9 @@ % delimited by a semicolon, form a fixed point number, so we pack it % in blocks of $4$ digits. % \begin{macrocode} -\cs_new:Npn \@@_exp_Taylor:Nnnwn #1#2#3 #4; #5 +\cs_new:Npn \@@_exp_Taylor:Nnnwn #1#2#3 #4; #5 #6 { + #6 \@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN @@ -749,7 +750,7 @@ % stream (we are currently within an \cs{__int_eval:w}), and keeping % track of a fixed point number, |#1| for the numbered auxiliaries. % Our usage of \cs{if_case:w} is somewhat dirty for optimization: -% \TeX{} jumps to the appropriate case, but we then lose the +% \TeX{} jumps to the appropriate case, but we then close the % \cs{if_case:w} \enquote{by hand}, using \cs{or:} and \cs{fi:} as % delimiters. % \begin{macrocode} @@ -860,9 +861,9 @@ #1; \@@_exp_large_after:wwn } -\cs_new:Npn \@@_exp_large_after:wwn #1; #2; +\cs_new:Npn \@@_exp_large_after:wwn #1; #2; #3 { - \@@_exp_Taylor:Nnnwn ? { } { } 0 #2; {} + \@@_exp_Taylor:Nnnwn ? { } { } 0 #2; {} #3 \@@_fixed_mul:wwn #1; } % \end{macrocode} @@ -942,10 +943,12 @@ % \begin{macro}[aux, EXP]{\@@_pow_zero_or_inf:ww} % Raising $-0$ or $-\infty$ to \texttt{nan} yields \texttt{nan}. For % other powers, the result is $+0$ if $0$ is raised to a positive -% power or $\infty$ to a negative power, and $+\infty$ otherwise. We -% can thus know the result by comparing the type of $a$ with the sign -% of $b$, since those conveniently take the same possible values, $0$ -% and~$2$. +% 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. % \begin{macrocode} \cs_new:Npn \@@_pow_zero_or_inf:ww \s_@@ \@@_chk:w #1#2; \s_@@ \@@_chk:w #3#4 { @@ -954,6 +957,13 @@ \fi: \if_meaning:w #1 #4 \@@_case_return_o:Nw \c_zero_fp + \fi: + \if_meaning:w 0 #1 + \@@_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: @@ -986,7 +996,7 @@ \fi: \@@_case_return_o:Nww \c_one_fp \fi: - \if_case:w #4 ~ + \if_case:w #4 \exp_stop_f: \or: \exp_after:wN \@@_pow_npos:Nww \exp_after:wN #5 @@ -1028,11 +1038,12 @@ \exp_after:wN 0 \__int_value:w \if:w #1 \if_int_compare:w #3 > \c_zero 0 \else: 2 \fi: - \exp_after:wN \@@_pow_npos_aux:Nnww + \exp_after:wN \@@_pow_npos_aux:NNnww + \exp_after:wN + \exp_after:wN \@@_fixed_to_float:wN \else: - - - \exp_after:wN \@@_pow_npos_aux:Nnww + \exp_after:wN \@@_pow_npos_aux:NNnww + \exp_after:wN - \exp_after:wN \@@_fixed_inv_to_float:wN \fi: {#3} @@ -1041,46 +1052,52 @@ % \end{macro} % %^^A begin[todo] -% \begin{macro}[aux, EXP]{\@@_pow_npos_aux:Nnww} +% \begin{macro}[aux, EXP]{\@@_pow_npos_aux:NNnww} % The first argument is the conversion function from fixed point to % float. Then comes an exponent and the $4$ brace groups of $x$, % followed by $b$. Compute $-\ln(x)$. % \begin{macrocode} -\cs_new:Npn \@@_pow_npos_aux:Nnww #1#2#3#4; \s_@@ \@@_chk:w 1#5#6#7; +\cs_new:Npn \@@_pow_npos_aux:NNnww #1#2#3#4#5; \s_@@ \@@_chk:w 1#6#7#8; { + #1 \__int_eval:w - \@@_ln_significand:NNNNnnnN #3#4 - \@@_pow_exponent:wnN {#2} - \@@_fixed_mul:wwn #7 {0000}{0000} ; - \@@_pow_B:wwN #6; - #1 0 % fixed_to_float:wN + \@@_ln_significand:NNNNnnnN #4#5 + \@@_pow_exponent:wnN {#3} + \@@_fixed_mul:wwn #8 {0000}{0000} ; + \@@_pow_B:wwN #7; + #1 #2 0 % fixed_to_float:wN } \cs_new:Npn \@@_pow_exponent:wnN #1; #2 { \if_int_compare:w #2 > \c_zero - \exp_after:wN \@@_pow_exponent:Nwnnnnnn % n\ln(10) - (-\ln(x)) + \exp_after:wN \@@_pow_exponent:Nwnnnnnwn % n\ln(10) - (-\ln(x)) \exp_after:wN + \else: - \exp_after:wN \@@_pow_exponent:Nwnnnnnn % -( |n|\ln(10) + (-\ln(x)) ) + \exp_after:wN \@@_pow_exponent:Nwnnnnnwn % -( |n|\ln(10) + (-\ln(x)) ) \exp_after:wN - \fi: #2; #1; } -\cs_new:Npn \@@_pow_exponent:Nwnnnnnn #1#2; #3#4#5#6#7#8; - { %^^A todo: use that in ln. %^^A todo: log(1.00...) too inaccurate? - \exp_after:wN \@@_fixed_mul_after:wwn - \int_use:N \__int_eval:w -5 0000 - \exp_after:wN \@@_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 #1#2*23025 - #1 #3 - \exp_after:wN \@@_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 #1 #2*8509 - #1 #4 - \exp_after:wN \@@_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 #1 #2*2994 - #1 #5 - \exp_after:wN \@@_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 #1 #2*0456 - #1 #6 - \exp_after:wN \@@_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 5 0000 0000 #1 #2*8401 - #1 #7 - #1 ( #2*7991 - #8 ) / 1 0000 ; ; +\cs_new:Npn \@@_pow_exponent:Nwnnnnnwn #1#2; #3#4#5#6#7#8; #9 + { %^^A todo: use that in ln. + \exp_after:wN \@@_fixed_mul_after:wn + \int_use:N \__int_eval:w \c_@@_leading_shift_int + \exp_after:wN \@@_pack:NNNNNwn + \int_use:N \__int_eval:w \c_@@_middle_shift_int + #1#2*23025 - #1 #3 + \exp_after:wN \@@_pack:NNNNNwn + \int_use:N \__int_eval:w \c_@@_middle_shift_int + #1 #2*8509 - #1 #4 + \exp_after:wN \@@_pack:NNNNNwn + \int_use:N \__int_eval:w \c_@@_middle_shift_int + #1 #2*2994 - #1 #5 + \exp_after:wN \@@_pack:NNNNNwn + \int_use:N \__int_eval:w \c_@@_middle_shift_int + #1 #2*0456 - #1 #6 + \exp_after:wN \@@_pack:NNNNNwn + \int_use:N \__int_eval:w \c_@@_trailing_shift_int + #1 #2*8401 - #1 #7 + #1 ( #2*7991 - #8 ) / 1 0000 ; {#9} ; } \cs_new:Npn \@@_pow_B:wwN #1#2#3#4#5#6; #7; { @@ -1097,7 +1114,7 @@ \int_use:N \__int_eval:w 10 0000 + #1 \__int_eval_end: #2#3#4#5#6 0000 0000 0000 0000 0000 0000 ; %^^A todo: how many 0? } -\cs_new:Npn \@@_pow_C_overflow:w #1; #2; +\cs_new:Npn \@@_pow_C_overflow:w #1; #2; #3 { + \c_two * \c_@@_max_exponent_int \exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl ; @@ -1129,11 +1146,11 @@ % \end{macro} %^^A end[todo] % -% \begin{macro}[aux, EXP]{\@@_pow_neg:www, \@@_pow_neg_neg:w} +% \begin{macro}[aux, EXP]{\@@_pow_neg:www} % This function is followed by three floating point numbers: $|a|^b$, % $a\in[-\infty,-0]$, and $b$. If $b$ is an even integer (case $-1$), % $a^b=|a|^b$. If $b$ is an odd integer (case $0$), $a^b=-|a|^b$, -% obtained by a call to \cs{@@_pow_neg_neg:w}. Otherwise, the sign is +% obtained by a call to \cs{@@_neg_o:w}. Otherwise, the sign is % 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 @@ -1143,7 +1160,7 @@ \cs_new:Npn \@@_pow_neg:www \s_@@ \@@_chk:w #1#2; #3; #4; { \if_case:w \@@_pow_neg_case:w #4 ; - \exp_after:wN \@@_pow_neg_neg:w + \exp_after:wN \@@_neg_o:w \or: \if_int_compare:w \__int_eval:w #1 / \c_two = \c_one \@@_invalid_operation_o:Nww ^ #3; #4; @@ -1155,14 +1172,6 @@ \@@_exp_after_o:w \s_@@ \@@_chk:w #1#2; } -\cs_new:Npn \@@_pow_neg_neg:w \@@_exp_after_o:w \s_@@ \@@_chk:w #1#2 - { - \exp_after:wN \@@_exp_after_o:w - \exp_after:wN \s_@@ - \exp_after:wN \@@_chk:w - \exp_after:wN #1 - \int_use:N \__int_eval:w \c_two - #2 \__int_eval_end: - } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx index febda1e81b1..b3952ea8aa5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-extended.dtx 2474 2011-06-17 12:54:02Z bruno $ +\GetIdInfo$Id: l3fp-extended.dtx 4151 2012-08-28 11:51:52Z bruno $ {L3 Floating-point extended precision fixed-points} \documentclass[full]{l3doc} \begin{document} @@ -77,6 +77,8 @@ %<@@=fp> % \end{macrocode} % +% \subsection{Description of extended fixed points} +% % In this module, we work on (almost) fixed-point numbers with % extended ($24$ digits) precision. This is used in the computation of % Taylor series for the logarithm, exponential, and trigonometric @@ -89,23 +91,28 @@ % \begin{quote} % \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;| % \end{quote} -% where each \meta{a_i} is exactly $4$ digits, except -% \meta{a_1}, which may be any positive \TeX{} integer. The fixed point +% where each \meta{a_i} is exactly $4$ digits (ranging from |0000| to +% |9999|), except \meta{a_1}, which may be any \enquote{not-too-large} +% non-negative integer, with or without trailing zeros. Here, +% \enquote{not-too-large} depends on the specific function (see the +% corresponding comments for details). Checking for overflow is the +% responsibility of the code calling those functions. The fixed point % number $a$ corresponding to the representation above is $a = % \sum_{i=1}^{6} \meta{a_i} \cdot 10^{-4i}$. % % Most functions we define here have the form % \begin{syntax} -% \cs{@@_fixed_\meta{calculation}:wwN} \meta{operand_1} |;| \meta{operand_2} |;| \meta{continuation} +% \cs{@@_fixed_\meta{calculation}:wwn} \meta{operand_1} |;| \meta{operand_2} |;| \Arg{continuation} % \end{syntax} % They perform the \meta{calculation} on the two \meta{operands}, then % feed the result ($6$ brace groups followed by a semicolon) to the % \meta{continuation}, responsible for the next step of the calculation. +% Some functions only accept an \texttt{N}-type \meta{continuation}. % This allows constructions such as % \begin{quote} -% \cs{@@_fixed_add:wwN} \meta{X_1} |;| \meta{X_2} |;| \\ +% \cs{@@_fixed_add:wwn} \meta{X_1} |;| \meta{X_2} |;| \\ % \cs{@@_fixed_mul:wwn} \meta{X_3} |;| \\ -% \cs{@@_fixed_add:wwN} \meta{X_4} |;| \\ +% \cs{@@_fixed_add:wwn} \meta{X_4} |;| \\ % \end{quote} % to compute $(X_1+X_2)\cdot X_3 + X_4$. This turns out to be very % appropriate for computing continued fractions and Taylor series. @@ -116,7 +123,10 @@ % after starting an integer expression for the overall exponent of the % result. % -% \begin{variable}{\c_@@_one_fixed_tl} +% \subsection{Helpers for extended fixed points} +% +% \begin{variable}[int]{\c_@@_one_fixed_tl} +% The extended fixed-point number~$1$, used in \pkg{l3fp-expo}. % \begin{macrocode} \tl_const:Nn \c_@@_one_fixed_tl { {10000} {0000} {0000} {0000} {0000} {0000} } @@ -124,38 +134,92 @@ % \end{variable} % % \begin{macro}[int, EXP]{\@@_fixed_continue:wn} -% This function does nothing. +% This function does nothing. Of course, there is no bound on +% $a_1$ (except \TeX{}'s own $2^{31}-1$). % \begin{macrocode} \cs_new:Npn \@@_fixed_continue:wn #1; #2 { #2 #1; } % \end{macrocode} % \end{macro} % +% \begin{macro}[int, EXP]{\@@_fixed_add_one:wN} +% \begin{syntax} +% \cs{@@_fixed_add_one:wN} \meta{a} |;| \meta{continuation} +% \end{syntax} +% This function adds $1$ to the fixed point \meta{a}, by changing +% $a_1$ to $10000+a_1$, then calls the \meta{continuation}. This +% requires $a_1 \leq 2^{31} - 10001$. +% \begin{macrocode} +\cs_new:Npn \@@_fixed_add_one:wN #1#2; #3 + { + \exp_after:wN #3 \exp_after:wN + { \int_use:N \__int_eval:w \c_ten_thousand + #1 } #2 ; + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux, EXP]{\@@_fixed_mul_after:wn} +% The fixed point operations which involve multiplication end by +% calling this auxiliary. It braces the last block of digits, and +% places the \meta{continuation} |#2| in front. The +% \meta{continuation} was brought up through the expansions by +% the packing functions. +% \begin{macrocode} +\cs_new:Npn \@@_fixed_mul_after:wn #1; #2 { #2 {#1} } +% \end{macrocode} +% \end{macro} +% +% \subsection{Dividing a fixed point number by a small integer} +% % \begin{macro}[int, EXP]{\@@_fixed_div_int:wwN} % \begin{macro}[aux, EXP] % { % \@@_fixed_div_int_i:wnN, \@@_fixed_div_int_ii:wnn, -% \@@_fixed_div_int_end:wnn, \@@_fixed_div_int_pack:Nw, +% \@@_fixed_div_int_iii:wnn, \@@_fixed_div_int_pack:Nw, % \@@_fixed_div_int_after:Nw % } % \begin{syntax} -% \cs{@@_fixed_div_int:wwN} \meta{a} |;| \meta{n} |;| \meta{function} +% \cs{@@_fixed_div_int:wwN} \meta{a} |;| \meta{n} |;| \meta{continuation} % \end{syntax} % Divides the fixed point number \meta{a} by the (small) integer -% $0<\meta{n}<10^4$ and feeds the result to the \meta{function}. The -% \texttt{wnN} auxiliary receives $a_{i}$, $n$, and a continuation -% function as arguments, and computes a (rather tight) lower bound -% $Q_{i}$ for the quotient. The \texttt{wnn} auxiliary receives -% $Q_{i}$, $n$, and $a_{i}$. It adds $Q_{i}$ to a surrounding integer -% expression, and starts a new one. It also computes $a_{i}-n\cdot -% Q_{i}$, putting the result in front of $a_{i+1}$ to serve as the -% first argument for a new call to the \texttt{wnN} auxiliary. At the -% end, the path we took to the lowest levels rewinds: the -% \texttt{pack} auxiliary receives $5$ digits, braces the last $4$, -% and carries the leading digit to the level above. The offsets used -% to ensure a given number of digits are as follows: we first subtract -% $1$ from the top-level, then add $9999$ at every subsequent level, -% and add $2$ to the last level. This last number is not $1$, because -% it compensates for the |- \c_one| in the \texttt{wnN} auxiliary. +% $0<\meta{n}<10^4$ and feeds the result to the \meta{continuation}. +% There is no bound on $a_1$. +% +% The arguments of the \texttt{i} auxiliary are 1: one of the $a_{i}$, +% 2: $n$, 3: the \texttt{ii} or the \texttt{iii} auxiliary. It +% computes a (somewhat tight) lower bound $Q_{i}$ for the ratio +% $a_{i}/n$. +% +% The \texttt{ii} auxiliary receives $Q_{i}$, $n$, and $a_{i}$ as +% arguments. It adds $Q_{i}$ to a surrounding integer expression, and +% starts a new one with the initial value $9999$, which ensures that +% the result of this expression will have $5$ digits. The auxiliary +% also computes $a_{i}-n\cdot Q_{i}$, placing the result in front of +% the $4$ digits of $a_{i+1}$. The resulting $a'_{i+1} = 10^{4} +% (a_{i} - n \cdot Q_{i}) + a_{i+1}$ serves as the first argument for +% a new call to the \texttt{i} auxiliary. +% +% When the \texttt{iii} auxiliary is called, the situation looks like +% this: +% \begin{quote} +% \cs{@@_fixed_div_int_after:Nw} \meta{continuation} \\ +% $-1 + Q_{1}$ \\ +% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{2}$ \\ +% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{3}$ \\ +% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{4}$ \\ +% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{5}$ \\ +% \cs{@@_fixed_div_int_pack:Nw} $9999$ \\ +% \cs{@@_fixed_div_int_iii:wnn} $Q_{6}$ |;| \Arg{n} \Arg{a_{6}} +% \end{quote} +% where expansion is happening from the last line up. The +% \texttt{iii} auxiliary adds $Q_{6} + 2 \simeq a_{6}/n + 1$ to the +% last $9999$, giving the integer closest to $10000 + a_{6}/n$. +% +% Each \texttt{pack} auxiliary receives $5$ digits followed by a +% semicolon. The first digit is added as a carry to the integer +% expression above, and the $4$ other digits are braced. Each call to +% the \texttt{pack} auxiliary thus produces one brace group. The last +% brace group is produced by the \texttt{after} auxiliary, which +% places the \meta{continuation} as appropriate. % \begin{macrocode} \cs_new:Npn \@@_fixed_div_int:wwN #1#2#3#4#5#6 ; #7 ; #8 { @@ -168,7 +232,7 @@ #3; {#7} \@@_fixed_div_int_ii:wnn #4; {#7} \@@_fixed_div_int_ii:wnn #5; {#7} \@@_fixed_div_int_ii:wnn - #6; {#7} \@@_fixed_div_int_end:wnn ; + #6; {#7} \@@_fixed_div_int_iii:wnn ; } \cs_new:Npn \@@_fixed_div_int_i:wnN #1; #2 #3 { @@ -185,185 +249,287 @@ \exp_after:wN \@@_fixed_div_int_i:wnN \int_use:N \__int_eval:w #3 - #1*#2 \__int_eval_end: } -\cs_new:Npn \@@_fixed_div_int_end:wnn #1; #2 #3 { + #1 + \c_two ; } +\cs_new:Npn \@@_fixed_div_int_iii:wnn #1; #2 #3 { + #1 + \c_two ; } \cs_new:Npn \@@_fixed_div_int_pack:Nw #1 #2; { + #1; {#2} } \cs_new:Npn \@@_fixed_div_int_after:Nw #1 #2; { #1 {#2} } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int, EXP]{\@@_fixed_add_one:wN} -% \begin{syntax} -% \cs{@@_fixed_add_one:wN} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \Arg{X_5} \Arg{X_6} |;| \meta{function} -% \end{syntax} -% \begin{macrocode} -\cs_new:Npn \@@_fixed_add_one:wN #1#2; #3 - { - \exp_after:wN #3 \exp_after:wN - { \int_use:N \__int_eval:w 10000 + #1 } #2 ; - } -% \end{macrocode} -% \end{macro} +% \subsection{Adding and subtracting fixed points} % -% \begin{macro}[int, EXP] -% {\@@_fixed_add:wwN, \@@_fixed_sub:wwN, \@@_fixed_sub_back:wwN} -%^^A todo: remove sub_back. +% \begin{macro}[int, EXP]{\@@_fixed_add:wwn, \@@_fixed_sub:wwn} % \begin{macro}[aux, EXP] % { -% \@@_fixed_add_i:NNnnnnwnn, -% \@@_fixed_add_ii:NnnNnnnnw, -% \@@_fixed_add_pack:NNNNNwN, -% \@@_fixed_add_after:NNNNNwN +% \@@_fixed_add_i:Nnnnnwnn, +% \@@_fixed_add_ii:nnNnnnwn, +% \@@_fixed_add_pack:NNNNNwn, +% \@@_fixed_add_after:NNNNNwn % } % \begin{syntax} -% \cs{@@_fixed_add:wwN} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \Arg{X_5} \Arg{X_6} |;| \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4} \Arg{Y_5} \Arg{Y_6} |;| \meta{function} +% \cs{@@_fixed_add:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation} % \end{syntax} -% Computes $X+Y$ (resp.\ $X-Y$ and $Y-X$) and feeds the result to -% \meta{function}. The three functions only differ by some signs and -% use a common auxiliary. It would be nice to grab the $12$ brace -% groups in one go, only $9$ arguments are allowed. Start by grabbing -% the two signs, $X_{1}, \ldots, X_{4}$, the rest of $X$, and $Y_{1}$ -% and $Y_{2}$. The second auxiliary receives the sign of $X$, the -% rest of $X$, the sign of $Y$, the rest of $Y$, and the -% \meta{function}. After going down through the various level, we go -% back up, packing digits and bringing the \meta{function} (|#9|, then -% |#7|) from the end of the argument list to its start. +% Computes $a+b$ (resp.\ $a-b$) and feeds the result to the +% \meta{continuation}. This function requires $0\leq +% a_{1},b_{1}<50000$, and requires the result to be positive (this +% happens automatically for addition). The two functions only differ +% a sign, hence use a common auxiliary. It would be nice to grab the +% $12$ brace groups in one go; only $9$ parameters are allowed. Start +% by grabbing the two signs, $a_{1}, \ldots, a_{4}$, the rest of $a$, +% and $b_{1}$ and $b_{2}$. The second auxiliary receives the rest of +% $a$, the sign multiplying $b$, the rest of $b$, and the +% \meta{continuation} as arguments. After going down through the +% various level, we go back up, packing digits and bringing the +% \meta{continuation} (|#8|, then |#7|) from the end of the argument +% list to its start. % \begin{macrocode} -\cs_new_nopar:Npn \@@_fixed_add:wwN { \@@_fixed_add_i:NNnnnnwnn + + } -\cs_new_nopar:Npn \@@_fixed_sub:wwN { \@@_fixed_add_i:NNnnnnwnn + - } -\cs_new_nopar:Npn \@@_fixed_sub_back:wwN { \@@_fixed_add_i:NNnnnnwnn - + } -\cs_new:Npn \@@_fixed_add_i:NNnnnnwnn #1#2 #3#4#5#6 #7; #8#9 - { - \exp_after:wN \@@_fixed_add_after:NNNNNwN - \int_use:N \__int_eval:w 1 9999 9998 #1 #3#4 #2 #8#9 - \exp_after:wN \@@_fixed_add_pack:NNNNNwN - \int_use:N \__int_eval:w 1 9999 9998 #1 #5#6 - \@@_fixed_add_ii:NnnNnnnnw #1 #7 #2 - } -\cs_new:Npn \@@_fixed_add_ii:NnnNnnnnw #1 #2#3 #4 #5#6 #7#8 ; #9 +\cs_new_nopar:Npn \@@_fixed_add:wwn { \@@_fixed_add_i:Nnnnnwnn + } +\cs_new_nopar:Npn \@@_fixed_sub:wwn { \@@_fixed_add_i:Nnnnnwnn - } +\cs_new:Npn \@@_fixed_add_i:Nnnnnwnn #1 #2#3#4#5 #6; #7#8 { - #4 #5#6 - \exp_after:wN \@@_fixed_add_pack:NNNNNwN - \int_use:N \__int_eval:w 2 0000 0000 #4 #7#8 #1 #2#3 ; #9 ; + \exp_after:wN \@@_fixed_add_after:NNNNNwn + \int_use:N \__int_eval:w 9 9999 9998 + #2#3 #1 #7#8 + \exp_after:wN \@@_fixed_add_pack:NNNNNwn + \int_use:N \__int_eval:w 1 9999 9998 + #4#5 + \@@_fixed_add_ii:nnNnnnwn #6 #1 } -\cs_new:Npn \@@_fixed_add_pack:NNNNNwN #1 #2#3#4#5 #6; #7 - { + #1 ; #7 {#2#3#4#5} {#6} } -\cs_new:Npn \@@_fixed_add_after:NNNNNwN #1 #2#3#4#5 #6; #7 +\cs_new:Npn \@@_fixed_add_ii:nnNnnnwn #1#2 #3 #4#5 #6#7 ; #8 { - \exp_after:wN #7 - \exp_after:wN { \int_use:N \__int_eval:w - 2 0000 + #1#2#3#4#5 } - {#6} + #3 #4#5 + \exp_after:wN \@@_fixed_add_pack:NNNNNwn + \int_use:N \__int_eval:w 2 0000 0000 #3 #6#7 + #1#2 ; {#8} ; } +\cs_new:Npn \@@_fixed_add_pack:NNNNNwn #1 #2#3#4#5 #6; #7 + { + #1 ; {#7} {#2#3#4#5} {#6} } +\cs_new:Npn \@@_fixed_add_after:NNNNNwn 1 #1 #2#3#4#5 #6; #7 + { #7 {#1#2#3#4#5} {#6} } % \end{macrocode} % \end{macro} % \end{macro} % +% \subsection{Multiplying fixed points} +% % \begin{macro}[int, EXP]{\@@_fixed_mul:wwn} -% \begin{macro}[aux, EXP] -% { -% \@@_fixed_mul_i:nnnnnnnn , -% \@@_fixed_mul_pack:NNNNNw , -% \@@_fixed_mul_after:wwn -% } +% \begin{macro}[aux, EXP]{\@@_fixed_mul_i:nnnnnnnwn} % \begin{syntax} -% \cs{@@_fixed_mul:wwn} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \Arg{X_5} \Arg{X_6} |;| \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4} \Arg{Y_5} \Arg{Y_6} |;| \Arg{tokens} +% \cs{@@_fixed_mul:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation} % \end{syntax} -% Computes $X\times Y$ and feeds the result to \meta{function}. It -% would be nice to grab the $12$ brace groups in one go, but that's -% not possible. On the other hand, we don't need to obtain an exact -% rounding, contrarily to the case in \cs{@@_*_o:ww}, so things are -% not quite as bad as they may seem. The parenthesis computing the -% seventh group of digits (computed because we need to know its -% potentially large carry) is closed by -% \cs{@@_fixed_mul_i:nnnnnnnn}, once we access the last two brace -% groups, which were not read before. Also, in -% \cs{@@_fixed_mul_after:wwn}, |#3| is the continuation -% tokens.\footnote{Bruno: insist on the difference compared to -% \cs{@@_fixed_add:wwN}.} +% Computes $a\times b$ and feeds the result to \meta{continuation}. +% This function requires $0\leq a_{1}, b_{1} < 10000$. Once more, we +% need to play around the limit of $9$ arguments for \TeX{} macros. +% Note that we don't need to obtain an exact rounding, contrarily to +% the |*| operator, so things could be harder. We wish to perform +% carries in +% \begin{align*} +% a \times b = +% & a_{1} \cdot b_{1} \cdot 10^{-8} \\ +% & + (a_{1} \cdot b_{2} + a_{2} \cdot b_{1}) \cdot 10^{-12} \\ +% & + (a_{1} \cdot b_{3} + a_{2} \cdot b_{2} +% + a_{3} \cdot b_{1}) \cdot 10^{-16} \\ +% & + (a_{1} \cdot b_{4} + a_{2} \cdot b_{3} +% + a_{3} \cdot b_{2} + a_{4} \cdot b_{1}) \cdot 10^{-20} \\ +% & + \left(a_{2} \cdot b_{4} + a_{3} \cdot b_{3} + a_{4} \cdot b_{2} +% + \frac{a_{3} \cdot b_{4} + a_{4} \cdot b_{3} +% + a_{1} \cdot b_{6} + a_{2} \cdot b_{5} +% + a_{5} \cdot b_{2} + a_{6} \cdot b_{1}}{10^{4}} +% + a_{1} \cdot b_{5} + a_{5} \cdot b_{1}\right) \cdot 10^{-24} +% + O(10^{-24}), +% \end{align*} +% where the $O(10^{-24})$ stands for terms which are at most $5\cdot +% 10^{-24}$; ignoring those leads to an error of at most +% $5$~\texttt{ulp}. Note how the first $15$~terms only depend on +% $a_{1},\ldots{},a_{4}$ and $b_{1},\ldots,b_{4}$, while the last +% $6$~terms only depend on $a_{1},a_{2},a_{5},a_{6}$, and the +% corresponding parts of~$b$. Hence, the first function grabs +% $a_{1},\ldots,a_{4}$, the rest of $a$, and $b_{1},\ldots,b_{4}$, and +% writes the $15$ first terms of the expression, including a left +% parenthesis for the fraction. The \texttt{i} auxiliary receives +% $a_{5}$, $a_{6}$, $b_{1}$, $b_{2}$, $a_{1}$, $a_{2}$, $b_{5}$, +% $b_{6}$ and finally the \meta{continuation} as arguments. It writes +% the end of the expression, including the right parenthesis and the +% denominator of the fraction. The packing auxiliaries bring the +% \meta{continuation} up through the expansion chain, as |#7|, and it +% is finally placed in front of the $6$ brace groups by +% \cs{@@_fixed_mul_after:wn}. % \begin{macrocode} \cs_new:Npn \@@_fixed_mul:wwn #1#2#3#4 #5; #6#7#8#9 { - \exp_after:wN \@@_fixed_mul_after:wwn + \exp_after:wN \@@_fixed_mul_after:wn \int_use:N \__int_eval:w \c_@@_leading_shift_int - \exp_after:wN \@@_pack:NNNNNw + \exp_after:wN \@@_pack:NNNNNwn \int_use:N \__int_eval:w \c_@@_middle_shift_int + #1*#6 - \exp_after:wN \@@_pack:NNNNNw + \exp_after:wN \@@_pack:NNNNNwn \int_use:N \__int_eval:w \c_@@_middle_shift_int + #1*#7 + #2*#6 - \exp_after:wN \@@_pack:NNNNNw + \exp_after:wN \@@_pack:NNNNNwn \int_use:N \__int_eval:w \c_@@_middle_shift_int + #1*#8 + #2*#7 + #3*#6 - \exp_after:wN \@@_pack:NNNNNw + \exp_after:wN \@@_pack:NNNNNwn \int_use:N \__int_eval:w \c_@@_middle_shift_int + #1*#9 + #2*#8 + #3*#7 + #4*#6 - \exp_after:wN \@@_pack:NNNNNw + \exp_after:wN \@@_pack:NNNNNwn \int_use:N \__int_eval:w \c_@@_trailing_shift_int + #2*#9 + #3*#8 + #4*#7 + ( #3*#9 + #4*#8 - + \@@_fixed_mul_i:nnnnnnnn #5 {#6}{#7} {#1}{#2} + + \@@_fixed_mul_i:nnnnnnnwn #5 {#6}{#7} {#1}{#2} + } +\cs_new:Npn \@@_fixed_mul_i:nnnnnnnwn #1#2 #3#4 #5#6 #7#8 ; #9 + { + #1*#4 + #2*#3 + #5*#8 + #6*#7 ) / \c_ten_thousand + + #1*#3 + #5*#7 ; + {#9} ; } -\cs_new:Npn \@@_fixed_mul_i:nnnnnnnn #1#2 #3#4 #5#6 #7#8 - { #1*#4 + #2*#3 + #5*#8 + #6*#7 )/10000 + #1*#3 + #5*#7 ; } -\cs_new:Npn \@@_fixed_mul_pack:NNNNNw - #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} } -\cs_new:Npn \@@_fixed_mul_after:wwn #1; #2; #3 { #3 {#1} #2 ; } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int, EXP]{\@@_fixed_mul_add:wwwn, \@@_fixed_mul_sub_back:wwwn} +% \subsection{Combining product and sum of fixed points} +% +% \begin{macro}[int, EXP] +% { +% \@@_fixed_mul_add:wwwn, +% \@@_fixed_mul_sub_back:wwwn, +% \@@_fixed_mul_one_minus_mul:wwn, +% } % \begin{syntax} -% \cs{@@_fixed_mul_add:wwn} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \Arg{X_5} \Arg{X_6} |;| \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4} \Arg{Y_5} \Arg{Y_6} |;| \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \Arg{Z_5} \Arg{Z_6} |;| \Arg{tokens} +% \cs{@@_fixed_mul_add:wwwn} \meta{a} |;| \meta{b} |;| \meta{c} |;| \Arg{continuation} +% \cs{@@_fixed_mul_sub_back:wwwn} \meta{a} |;| \meta{b} |;| \meta{c} |;| \Arg{continuation} +% \cs{@@_fixed_one_minus_mul:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation} % \end{syntax} -% These functions compute $X\times Y + Z$ or $Z-X\times Y$ and feed -% the result to the \meta{tokens}. This is tough because we have $18$ -% brace groups in front of us. +% Compute $a\times b + c$, $c - a\times b$, and $1 - a\times b$ and +% feed the result to the \meta{continuation}. Those functions require +% $0\leq a_{1}, b_{1}, c_{1} \leq 10000$. Since those functions are +% at the heart of the computation of Taylor expansions, we +% over-optimize them a bit, and in particular we do not factor out the +% common parts of the three functions. +% +% For definiteness, consider the task of computing $a\times b + c$. +% We will perform carries in +% \begin{align*} +% a \times b + c = +% & (a_{1} \cdot b_{1} + c_{1} c_{2})\cdot 10^{-8} \\ +% & + (a_{1} \cdot b_{2} + a_{2} \cdot b_{1}) \cdot 10^{-12} \\ +% & + (a_{1} \cdot b_{3} + a_{2} \cdot b_{2} + a_{3} \cdot b_{1} +% + c_{3} c_{4}) \cdot 10^{-16} \\ +% & + (a_{1} \cdot b_{4} + a_{2} \cdot b_{3} + a_{3} \cdot b_{2} +% + a_{4} \cdot b_{1}) \cdot 10^{-20} \\ +% & + \Big(a_{2} \cdot b_{4} + a_{3} \cdot b_{3} + a_{4} \cdot b_{2} +% + \frac{a_{3} \cdot b_{4} + a_{4} \cdot b_{3} +% + a_{1} \cdot b_{6} + a_{2} \cdot b_{5} +% + a_{5} \cdot b_{2} + a_{6} \cdot b_{1}}{10^{4}} +% + a_{1} \cdot b_{5} + a_{5} \cdot b_{1} +% + c_{5} c_{6} \Big) \cdot 10^{-24} +% + O(10^{-24}), +% \end{align*} +% where $c_{1} c_{2}$, $c_{3} c_{4}$, $c_{5} c_{6}$ denote the +% $8$-digit number obtained by juxtaposing the two blocks of digits of +% $c$, and $\cdot$ denotes multiplication. The task is obviously +% tough because we have $18$ brace groups in front of us. +% +% Each of the three function starts the first two levels (the first, +% corresponding to $10^{-4}$, is empty), with $c_{1} c_{2}$ in the +% first level, calls the \texttt{i} auxiliary with arguments described +% later, and adds a trailing ${} + c_{5}c_{6}$ |;| +% \Arg{continuation}~|;|. The ${} + c_{5}c_{6}$ piece, which is +% omitted for \cs{@@_fixed_one_minus_mul:wwn}, will be taken in the +% integer expression for the $10^{-24}$ level. The +% \meta{continuation} is placed correctly to be taken upstream by +% packing auxiliaries. % \begin{macrocode} -\cs_new:Npn \@@_fixed_one_minus_mul:wwn #1; #2#3#4#5; +\cs_new:Npn \@@_fixed_mul_add:wwwn #1; #2; #3#4#5#6#7#8; #9 { - \exp_after:wN \@@_fixed_mul_after:wwn - \int_use:N \__int_eval:w \c_@@_big_leading_shift_int + \c_ten_thousand - \exp_after:wN \@@_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c_@@_big_middle_shift_int - \@@_fixed_mul_add_i:Nnwnnwnnn - - 00; {#2}{#3}{#4}; #1; {#2}{#3}{#4}#5; - 00 ; + \exp_after:wN \@@_fixed_mul_after:wn + \int_use:N \__int_eval:w \c_@@_big_leading_shift_int + \exp_after:wN \@@_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #3 #4 + \@@_fixed_mul_add_i:Nwnnnwnnn + + + #5 #6 ; #2 ; #1 ; #2 ; + + + #7 #8 ; {#9} ; } -\cs_new:Npn \@@_fixed_mul_add:wwwn #1; #2#3#4#5; #6#7#8#9 +\cs_new:Npn \@@_fixed_mul_sub_back:wwwn #1; #2; #3#4#5#6#7#8; #9 { - \exp_after:wN \@@_fixed_mul_after:wwn - \int_use:N \__int_eval:w \c_@@_big_leading_shift_int + #6 - \exp_after:wN \@@_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #7 - \@@_fixed_mul_add_i:Nnwnnwnnn - + {#8}{#9}; {#2}{#3}{#4}; #1; {#2}{#3}{#4}#5; + + \exp_after:wN \@@_fixed_mul_after:wn + \int_use:N \__int_eval:w \c_@@_big_leading_shift_int + \exp_after:wN \@@_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #3 #4 + \@@_fixed_mul_add_i:Nwnnnwnnn - + + #5 #6 ; #2 ; #1 ; #2 ; - + + #7 #8 ; {#9} ; } -\cs_new:Npn \@@_fixed_mul_sub_back:wwwn #1; #2#3#4#5; #6#7#8#9 +\cs_new:Npn \@@_fixed_one_minus_mul:wwn #1; #2; #3 { - \exp_after:wN \@@_fixed_mul_after:wwn - \int_use:N \__int_eval:w \c_@@_big_leading_shift_int + #6 - \exp_after:wN \@@_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #7 - \@@_fixed_mul_add_i:Nnwnnwnnn - - {#8}{#9}; {#2}{#3}{#4}; #1; {#2}{#3}{#4}#5; - + \exp_after:wN \@@_fixed_mul_after:wn + \int_use:N \__int_eval:w \c_@@_big_leading_shift_int + \exp_after:wN \@@_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + 1 0000 0000 + \@@_fixed_mul_add_i:Nwnnnwnnn - + ; #2 ; #1 ; #2 ; - + ; {#3} ; } -\cs_new:Npn \@@_fixed_mul_add_i:Nnwnnwnnn #1 #2#3; #4#5#6; #7#8#9 - { % sg z3z4; y1y2y3; x1x2x3 x4x5x6; y1y2y3y4y5y6; sg z5z6; - #1 #7*#4 - \exp_after:wN \@@_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #2 - #1 #7*#5 #1 #8*#4 - \exp_after:wN \@@_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #3 - #1 #7*#6 #1 #8*#5 #1 #9*#4 - \exp_after:wN \@@_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c_@@_big_middle_shift_int - #1 \@@_fixed_mul_add_ii:nnnnwnnnn {#7}{#8}{#9} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux, EXP]{\@@_fixed_mul_add_i:Nwnnnwnnn} +% \begin{syntax} +% \cs{@@_fixed_mul_add_i:Nwnnnwnnn} \meta{op} |+| \meta{c_3} \meta{c_4} |;| +% ~~\meta{b} |;| \meta{a} |;| \meta{b} |;| \meta{op} +% ~~|+| \meta{c_5} \meta{c_6} |;| +% \end{syntax} +% Here, \meta{op} is either |+| or |-|. Arguments |#3|, |#4|, |#5| +% are \meta{b_1}, \meta{b_2}, \meta{b_3}; arguments |#7|, |#8|, |#9| +% are \meta{a_1}, \meta{a_2}, \meta{a_3}. We can build three levels: +% $a_{1} \cdot b_{1}$ for $10^{-8}$, $(a_{1} \cdot b_{2} + a_{2} \cdot +% b_{1})$ for $10^{-12}$, and $(a_{1} \cdot b_{3} + a_{2} \cdot b_{2} +% + a_{3} \cdot b_{1} + c_{3} c_{4})$ for $10^{-16}$. The $a$--$b$ +% products huse the sign |#1|. Note that |#2| is empty for +% \cs{@@_fixed_one_minus_mul:wwn}. We call the \texttt{ii} auxiliary +% for levels $10^{-20}$ and $10^{-24}$, keeping the pieces of \meta{a} +% we've read, but not \meta{b}, since there is another copy later in +% the input stream. +% \begin{macrocode} +\cs_new:Npn \@@_fixed_mul_add_i:Nwnnnwnnn #1 #2; #3#4#5#6; #7#8#9 + { + #1 #7*#3 + \exp_after:wN \@@_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #1 #7*#4 #1 #8*#3 + \exp_after:wN \@@_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #1 #7*#5 #1 #8*#4 #1 #9*#3 #2 + \exp_after:wN \@@_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c_@@_big_middle_shift_int + #1 \@@_fixed_mul_add_ii:nnnnwnnnn {#7}{#8}{#9} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux, EXP]{\@@_fixed_mul_add_ii:nnnnwnnnn} +% \begin{syntax} +% \cs{@@_fixed_mul_add_ii:nnnnwnnnn} \meta{a} |;| \meta{b} |;| \meta{op} +% ~~|+| \meta{c_5} \meta{c_6} |;| +% \end{syntax} +% Level $10^{-20}$ is $(a_{1} \cdot b_{4} + a_{2} \cdot b_{3} + a_{3} +% \cdot b_{2} + a_{4} \cdot b_{1})$, multiplied by the sign, which was +% inserted by the \texttt{i} auxiliary. Then we prepare level +% $10^{-24}$. We don't have access to all parts of \meta{a} and +% \meta{b} needed to make all products. Instead, we prepare the +% partial expressions +% \begin{align*} +% & b_{1} + a_{4} \cdot b_{2} + a_{3} \cdot b_{3} + a_{2} \cdot b_{4} + a_{1} \\ +% & b_{2} + a_{4} \cdot b_{3} + a_{3} \cdot b_{4} + a_{2} . +% \end{align*} +% Obviously, those expressions make no mathematical sense: we will +% complete them with $a_{5} \cdot {}$ and ${} \cdot b_{5}$, and with +% $a_{6} \cdot b_{1} + a_{5} \cdot {}$ and ${} \cdot b_{5} + a_{1} +% \cdot b_{6}$, and of course with the trailing ${} + c_{5} c_{6}$. +% To do all this, we keep $a_{1}$, $a_{5}$, $a_{6}$, and the +% corresponding pieces of \meta{b}. +% \begin{macrocode} \cs_new:Npn \@@_fixed_mul_add_ii:nnnnwnnnn #1#2#3#4#5; #6#7#8#9 - { % x1x2x3x4 x5x6; y1y2y3y4 y5y6; sg z5z6; + { ( #1*#9 + #2*#8 + #3*#7 + #4*#6 ) - \exp_after:wN \@@_pack_big:NNNNNNw + \exp_after:wN \@@_pack_big:NNNNNNwn \int_use:N \__int_eval:w \c_@@_big_trailing_shift_int \@@_fixed_mul_add_iii:nnnnwnnwN { #6 + #4*#7 + #3*#8 + #2*#9 + #1 } @@ -371,25 +537,37 @@ {#1} #5; {#6} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux, EXP]{\@@_fixed_mul_add_iii:nnnnwnnwN} +% \begin{syntax} +% \cs{@@_fixed_mul_add_iii:nnnnwnnwN} \Arg{partial_1} \Arg{partial_2} +% ~~\Arg{a_1} \Arg{a_5} \Arg{a_6} |;| \Arg{b_1} \Arg{b_5} \Arg{b_6} |;| +% ~~\meta{op} |+| \meta{c_5} \meta{c_6} |;| +% \end{syntax} +% Complete the \meta{partial_1} and \meta{partial_2} expressions as +% explained for the \texttt{ii} auxiliary. The second one is divided +% by $10000$: this is the carry from level $10^{-28}$. The trailing +% ${} + c_{5} c_{6}$ is taken into the expression for level +% $10^{-24}$. Note that the total of level $10^{-24}$ is in the +% interval $[-5\cdot 10^{8}, 6\cdot 10^{8}$ (give or take a couple of +% $10000$), hence adding it to the shift gives a $10$-digit number, as +% expected by the packing auxiliaries. See \pkg{l3fp-aux} for the +% definition of the shifts and packing auxiliaries. +% \begin{macrocode} \cs_new:Npn \@@_fixed_mul_add_iii:nnnnwnnwN #1#2 #3#4#5; #6#7#8; #9 - { % {y1+x4*y2+x3*y3+x2*y4+x1} {y2+x4*y3+x3*y4+x2} - % x1x5x6; y1y5y6; sg z5z6; - % => - % sg (x5*y1+x4*y2+x3*y3+x2*y4+x1*y5) - % sg (x6*y1+x5*y2+x4*y3+x3*y4+x2*y5+x1*y6)/10000 - % + z5z6; + { #9 (#4* #1 *#7) #9 (#5*#6+#4* #2 *#7+#3*#8) / \c_ten_thousand - + \@@_use_s:nn } % \end{macrocode} % \end{macro} % -% \begin{macrocode} -\cs_new:Npn \@@_fixed_to_float:Nw #1#2; { \@@_fixed_to_float:wN #2; #1 } -% \end{macrocode} +% \subsection{Converting from fixed point to floating point} % -% \begin{macro}[int, rEXP]{\@@_fixed_to_float:wN} +% \begin{macro}[int, rEXP] +% {\@@_fixed_to_float:wN, \@@_fixed_to_float:Nw} % \begin{syntax} % \ldots{} \cs{__int_eval:w} \meta{exponent} \cs{@@_fixed_to_float:wN} \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;| \meta{sign} % \end{syntax} @@ -405,6 +583,7 @@ % %^^A todo: round properly when rounding to infinity: I need to know the sign. % \begin{macrocode} +\cs_new:Npn \@@_fixed_to_float:Nw #1#2; { \@@_fixed_to_float:wN #2; #1 } \cs_new:Npn \@@_fixed_to_float:wN #1#2#3#4#5#6; #7 { + \c_four % for the 8-digit-at-the-start thing. @@ -471,7 +650,7 @@ % \begin{macrocode} \cs_new:Npn \@@_fixed_inv_to_float:wN #1#2; #3 { - - \__int_eval:w + + \__int_eval:w % ^^A todo: remove the +? \if_int_compare:w #1 < \c_one_thousand \@@_fixed_dtf_zeros:wNnnnnnn \fi: @@ -654,7 +833,7 @@ { #1 ; {#2#3#4#5} {#6} } \cs_new:Npn \@@_fixed_dtf_epsilon_ii:NNNNNww #1#2#3#4#5#6; #7; { - \@@_fixed_mul:wwn %^^A todo: optimize to use \@@_mul_mantissa. + \@@_fixed_mul:wwn %^^A todo: optimize to use \@@_mul_significand. {0000} {#2#3#4#5} {#6} #7 ; {0000} {#2#3#4#5} {#6} #7 ; \@@_fixed_add_one:wN diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index 9813509686d..20f94e2abe4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx @@ -205,7 +205,7 @@ % \end{macro} % % \begin{macro}[int, EXP]{\@@_compare_npos:nwnw} -% \begin{macro}[aux, EXP]{\@@_compare_mantissa:nnnnnnnn} +% \begin{macro}[aux, EXP]{\@@_compare_significand:nnnnnnnn} % \begin{quote} % \cs{@@_compare_npos:nwnw} % \Arg{expo_1} \meta{body_1} |;| @@ -215,7 +215,7 @@ % this expands to $0$ if the two numbers are equal, $-1$ if the first % is smaller, and $1$ if the first is bigger. First compare the % exponents: the larger one denotes the larger number. If they are -% equal, we must compare mantissas. If both the first $8$ digits and +% equal, we must compare significands. If both the first $8$ digits and % the next $8$ digits coincide, the numbers are equal. If only the % first $8$ digits coincide, the next $8$ decide. Otherwise, the % first $8$ digits are compared. @@ -223,12 +223,12 @@ \cs_new:Npn \@@_compare_npos:nwnw #1#2; #3#4; { \if_int_compare:w #1 = #3 \exp_stop_f: - \@@_compare_mantissa:nnnnnnnn #2 #4 + \@@_compare_significand:nnnnnnnn #2 #4 \else: \if_int_compare:w #1 < #3 - \fi: 1 \fi: } -\cs_new:Npn \@@_compare_mantissa:nnnnnnnn #1#2#3#4#5#6#7#8 +\cs_new:Npn \@@_compare_significand:nnnnnnnn #1#2#3#4#5#6#7#8 { \if_int_compare:w #1#2 = #5#6 \exp_stop_f: \if_int_compare:w #3#4 = #7#8 \exp_stop_f: @@ -244,6 +244,86 @@ % \end{macro} % \end{macro} % +% \subsection{Floating point expression loops} +% +% \begin{macro}[rEXP] +% { +% \fp_do_until:nn, \fp_do_while:nn, +% \fp_until_do:nn, \fp_while_do:nn +% } +% These are quite easy given the above functions. The |do_until| and +% |do_while| versions execute the body, then test. The |until_do| and +% |while_do| do it the other way round. +% \begin{macrocode} +\cs_new:Npn \fp_do_until:nn #1#2 + { + #2 + \fp_compare:nF {#1} + { \fp_do_until:nn {#1} {#2} } + } +\cs_new:Npn \fp_do_while:nn #1#2 + { + #2 + \fp_compare:nT {#1} + { \fp_do_while:nn {#1} {#2} } + } +\cs_new:Npn \fp_until_do:nn #1#2 + { + \fp_compare:nF {#1} + { + #2 + \fp_until_do:nn {#1} {#2} + } + } +\cs_new:Npn \fp_while_do:nn #1#2 + { + \fp_compare:nT {#1} + { + #2 + \fp_while_do:nn {#1} {#2} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[rEXP] +% { +% \fp_do_until:nNnn, \fp_do_while:nNnn, +% \fp_until_do:nNnn, \fp_while_do:nNnn +% } +% As above but not using the |nNn| syntax. +% \begin{macrocode} +\cs_new:Npn \fp_do_until:nNnn #1#2#3#4 + { + #4 + \fp_compare:nNnF {#1} #2 {#3} + { \fp_do_until:nNnn {#1} #2 {#3} {#4} } + } +\cs_new:Npn \fp_do_while:nNnn #1#2#3#4 + { + #4 + \fp_compare:nNnT {#1} #2 {#3} + { \fp_do_while:nNnn {#1} #2 {#3} {#4} } + } +\cs_new:Npn \fp_until_do:nNnn #1#2#3#4 + { + \fp_compare:nNnF {#1} #2 {#3} + { + #4 + \fp_until_do:nNnn {#1} #2 {#3} {#4} + } + } +\cs_new:Npn \fp_while_do:nNnn #1#2#3#4 + { + \fp_compare:nNnT {#1} #2 {#3} + { + #4 + \fp_while_do:nNnn {#1} #2 {#3} {#4} + } + } +% \end{macrocode} +% \end{macro} +% % \subsection{Extrema} % % \begin{macro}[int, EXP]{\@@_max_o:w, \@@_min_o:w} @@ -403,7 +483,7 @@ \@@_ternary_break_point:n { \exp_after:wN \@@_ternary_i:NwwN } \exp_after:wN #1 \tex_romannumeral:D -`0 - \@@_parse_exp_after_array:wf #3 \s_@@_stop + \@@_exp_after_array_f:w #3 \s_@@_stop \exp_after:wN @ \tex_romannumeral:D \@@_parse_until:Nw \c_two @@ -414,7 +494,7 @@ \exp_after:wN \@@_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 - \@@_parse_exp_after_array:wf #3 \s_@@_stop + \@@_exp_after_array_f:w #3 \s_@@_stop \exp_after:wN #4 \exp_after:wN #1 \fi: @@ -437,7 +517,7 @@ \exp_after:wN \@@_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 - \@@_parse_exp_after_array:wf #2 \s_@@_stop + \@@_exp_after_array_f:w #2 \s_@@_stop #4 #1 } \cs_new:Npn \@@_ternary_ii:NwwN #1#2@#3@#4 @@ -445,7 +525,7 @@ \exp_after:wN \@@_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 - \@@_parse_exp_after_array:wf #3 \s_@@_stop + \@@_exp_after_array_f:w #3 \s_@@_stop #4 #1 } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index f74c2cf0a92..bb9c792adff 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-parse.dtx 4081 2012-08-12 11:06:18Z bruno $ +\GetIdInfo$Id: l3fp-parse.dtx 4159 2012-08-29 13:21:59Z bruno $ {L3 Floating-point expression parsing} \documentclass[full]{l3doc} \begin{document} @@ -119,7 +119,6 @@ % \item[-1] Start and end of the expression. % \end{itemize} % -% ^^A todo: change 'mantissa' => 'significand' everywhere. % ^^A todo: ask SO when sNaN can arise. % % \section{Evaluating an expression} @@ -754,7 +753,7 @@ % %^^A end[todo] % -% \begin{macro}[rEXP, aux]{\@@_parse_expand:w} +% \begin{macro}[aux, rEXP]{\@@_parse_expand:w} % \begin{syntax} % \cs{tex_romannumeral:D} \cs{@@_parse_expand:w} \meta{tokens} % \end{syntax} @@ -767,7 +766,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP, aux]{\@@_parse_return_semicolon:w} +% \begin{macro}[aux, EXP]{\@@_parse_return_semicolon:w} % This very odd function swaps its position with the following % \cs{fi:} and removes \cs{@@_parse_expand:w} normally responsible for % expansion. That turns out to be useful. @@ -779,13 +778,13 @@ % % \subsection{Fp object type} % -% \begin{macro}[EXP, int]{\@@_type_from_scan:N} +% \begin{macro}[aux, EXP]{\@@_type_from_scan:N, \@@_type_from_scan:w} % \begin{syntax} % \cs{@@_type_from_scan:N} \meta{token} % \end{syntax} % Grabs the pieces of the stringified \meta{token} which lies after % the first |s__fp|. If the \meta{token} does not contain that -% string, the result is empty. +% string, the result is |_?|. % \begin{macrocode} \group_begin: \char_set_catcode_other:N \S @@ -798,7 +797,7 @@ \cs_new:Npn \@@_type_from_scan:N #1 { \exp_after:wN \@@_type_from_scan:w - \token_to_str:N #1 \q_mark S--FP \q_mark \q_stop + \token_to_str:N #1 \q_mark S--FP-? \q_mark \q_stop } \cs_new:Npn \@@_type_from_scan:w #1 S--FP #2 \q_mark #3 \q_stop {#2} } @@ -955,47 +954,50 @@ % \end{macro} % % \begin{macro}[aux, EXP] -% {\@@_parse_operand_relax:NN, \@@_parse_operand_relax_aux:wwnw} The -% argument is a token equal to \cs{tex_relax:D}. This can be -% \cs{s_@@}, \cs{s_@@_mark}, or a badly initialized register. We make -% sure that the last argument of \cs{@@_parse_infix:NN} is +% { +% \@@_parse_operand_relax:NN, +% \@@_exp_after_mark_f:nw, +% \@@_exp_after_?_f:nw +% } +% The second argument is a control sequence equal to \cs{tex_relax:D}. +% There are three cases, dispatched using \cs{@@_type_from_scan:N}. +% \begin{itemize} +% \item \cs{s_@@} starts a floating point number, and we call +% \cs{@@_exp_after_f:nw}. +% \item \cs{s_@@_mark} is a premature end, we call +% \cs{@@_exp_after_mark_f:nw}, which triggers the appropriate +% error. +% \item For a control sequence not containing |\s__fp|, we call +% \cs{@@_exp_after_?_f:nw}, causing a |bad-variable| error. +% \end{itemize} +% This scheme is extensible: additional types can be added by starting +% the variables with a scan mark of the form |\s__fp_|\meta{type} and +% defining |\__fp_exp_after_|\meta{type}|_f:nw|. In all cases, we +% make sure that the last argument of \cs{@@_parse_infix:NN} is % correctly expanded. % \begin{macrocode} \cs_new:Npn \@@_parse_operand_relax:NN #1#2 { - \@@_parse_operand_relax_aux:wwnw - #2 \s_@@_mark - { - \@@_exp_after_o:nw - { - \tex_romannumeral:D -`0 - \exp_after:wN \@@_parse_infix:NN - \exp_after:wN #1 \tex_romannumeral:D \@@_parse_expand:w - } - \s_@@ - } - \s_@@ #2 - { - \__msg_kernel_expandable_error:nn { kernel } { fp-early-end } - \exp_after:wN \c_nan_fp - \tex_romannumeral:D -`0 - \@@_parse_infix:NN #1 - \s_@@_mark - } - \s_@@_mark - { - \__msg_kernel_expandable_error:nnn - { kernel } { bad-variable } {#2} - \exp_after:wN \c_nan_fp - \tex_romannumeral:D -`0 - \exp_after:wN \@@_parse_infix:NN - \exp_after:wN #1 - \tex_romannumeral:D \@@_parse_expand:w - } - \s_@@_mark \s_@@_stop - } -\cs_new:Npn \@@_parse_operand_relax_aux:wwnw - #1 \s_@@ #2 \s_@@_mark #3 #4 \s_@@_mark \s_@@_stop { #3 } + \cs:w @@_exp_after \@@_type_from_scan:N #2 _f:nw \cs_end: + { + \exp_after:wN \@@_parse_infix:NN + \exp_after:wN #1 \tex_romannumeral:D \@@_parse_expand:w + } + #2 + } +\cs_new:Npn \@@_exp_after_mark_f:nw #1 + { + \__msg_kernel_expandable_error:nn { kernel } { fp-early-end } + \exp_after:wN \c_nan_fp + \tex_romannumeral:D -`0 #1 + } +\cs_new:cpn { @@_exp_after_?_f:nw } #1#2 + { + \__msg_kernel_expandable_error:nnn + { kernel } { bad-variable } {#2} + \exp_after:wN \c_nan_fp + \tex_romannumeral:D -`0 #1 + } % \end{macrocode} % \end{macro} % @@ -1356,9 +1358,9 @@ % shift as its first argument, which we add to the exponent found in % the |e...| syntax. If the trailing digits cause a carry, the % integer expression for the leading digits is incremented (|+ \c_one| -% in the code below). If the leading digits propagte this carry all +% in the code below). If the leading digits propagate this carry all % the way up, the function \cs{@@_parse_pack_carry:w} increments the -% exponent, and changes the mantissa from |0000...| to |1000...|: this +% exponent, and changes the significand from |0000...| to |1000...|: this % is simple because such a carry can only occur to give rise to a % power of $10$. % \begin{macrocode} @@ -1998,8 +2000,9 @@ \cs:w @@ \@@_type_from_scan:N #2 + _ #4 \@@_type_from_scan:N #5 - _ #4 _o:ww + _o:ww \cs_end: #2#3 #5#6 \tex_romannumeral:D -`0 #7 #1 @@ -2092,15 +2095,18 @@ % \@@_parse_word_abs:N , % \@@_parse_word_cos:N , % \@@_parse_word_cot:N , +% \@@_parse_word_csc:N , % \@@_parse_word_exp:N , % \@@_parse_word_ln:N , +% \@@_parse_word_sec:N , % \@@_parse_word_sin:N , % \@@_parse_word_tan:N , % } % Unary functions, which are applied to all of their arguments when % receiving an array. % \begin{macrocode} -\tl_map_inline:nn { {abs} {cos} {cot} {exp} {ln} {sin} {tan} } +\tl_map_inline:nn + { {abs} {cos} {cot} {csc} {exp} {ln} {sec} {sin} {tan} } { \cs_new:cpn { @@_parse_word_#1:N } ##1 { @@ -2234,7 +2240,7 @@ { \token_if_eq_meaning:NNTF #3 \@@_parse_infix_):N { - \@@_parse_exp_after_array:wf #2 \s_@@_stop + \@@_exp_after_array_f:w #2 \s_@@_stop \exp_after:wN \@@_parse_infix:NN \exp_after:wN #1 \tex_romannumeral:D \@@_parse_expand:w @@ -2248,16 +2254,15 @@ % \end{macrocode} % \end{macro} % -%^^A todo: rename to exp_after_array_f:w -% \begin{macro}[int, EXP]{\@@_parse_exp_after_array:wf} +% \begin{macro}[int, EXP]{\@@_exp_after_array_f:w} % \begin{macrocode} -\cs_new:Npn \@@_parse_exp_after_array:wf #1 +\cs_new:Npn \@@_exp_after_array_f:w #1 { - \cs:w @@ \@@_type_from_scan:N #1 _exp_after_f:nw \cs_end: - { \@@_parse_exp_after_array:wf } + \cs:w @@_exp_after \@@_type_from_scan:N #1 _f:nw \cs_end: + { \@@_exp_after_array_f:w } #1 } -\cs_new:Npn \@@_stop_exp_after_f:nw #1#2 { } +\cs_new:Npn \@@_exp_after_stop_f:nw #1#2 { } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx index b14d3e1058f..b485a0616c3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx @@ -89,7 +89,7 @@ % \subsection{Rounding tools} % % Floating point operations often yield a result that cannot be exactly -% represented in a mantissa with $16$ digits. In that case, we need to +% represented in a significand with $16$ digits. In that case, we need to % round the exact result to a representable number. The \textsc{ieee} % standard defines four rounding modes: % \begin{itemize} @@ -329,7 +329,10 @@ \cs_new:Npn \@@_round:Nww #1#2 ; #3 ; { \@@_small_int:wTF #3; { \@@_round:Nwn #1#2; } - { \@@_array_invalid_operation_o:nw { round } #2; #3; @ } + { + \@@_invalid_operation_tl_o:nf + { round } { \@@_array_to_clist:n { #2; #3; } } + } } \cs_new:Npn \@@_round:Nwn #1 \s_@@ \@@_chk:w #2#3#4; #5 { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index f3e3955c1b1..107b94ac0ca 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-traps.dtx 2479 2011-06-19 21:57:25Z bruno $ +\GetIdInfo$Id: l3fp-traps.dtx 4129 2012-08-20 20:38:28Z mittelba $ {L3 Floating-point exception trapping} \documentclass[full]{l3doc} \begin{document} @@ -118,7 +118,7 @@ % \end{macrocode} % \end{macro} % -% \begin{variable} +% \begin{variable}[aux] % { % \l_@@_invalid_operation_flag_token , % \l_@@_division_by_zero_flag_token , @@ -152,7 +152,7 @@ % \begin{itemize} % \item \cs{@@_invalid_operation:nnw}, % \item \cs{@@_invalid_operation_o:Nww}, -% \item \cs{@@_array_invalid_operation_o:nw}, +% \item \cs{@@_invalid_operation_tl_o:nf}, % \item \cs{@@_division_by_zero_o:Nnw}, % \item \cs{@@_division_by_zero_o:NNww}, % \item \cs{@@_overflow:w}, @@ -163,7 +163,10 @@ % \meta{way of trapping} is one of \texttt{error}, \texttt{flag}, or % \texttt{none}. % -% \begin{macro}{\fp_trap:nn} %^^A todo: user command => document +% We also provide \cs{@@_invalid_operation_o:nw}, defined in terms of +% \cs{@@_invalid_operation:nnw}. +% +% \begin{macro}{\fp_trap:nn} % \begin{macrocode} \cs_new_protected:Npn \fp_trap:nn #1#2 { @@ -207,7 +210,7 @@ { \cs_set:Npn \@@_invalid_operation:nnw ##1##2##3; } { #1 - \@@_error:nffn { invalid } {##2} { \@@_to_tl:w ##3; } { } + \@@_error:nnfn { invalid } {##2} { \@@_to_tl:w ##3; } { } \fp_flag_on:n { invalid_operation } ##1 } @@ -221,11 +224,10 @@ \exp_after:wN \c_nan_fp } \exp_args:Nno \use:n - { \cs_set:Npn \@@_array_invalid_operation_o:nw ##1##2@ } + { \cs_set:Npn \@@_invalid_operation_tl_o:nf ##1##2 } { #1 - \@@_error:nffn { invalid } - {##1} { \@@_array_to_clist:w ##2 @ } { } + \@@_error:nnfn { invalid } {##1} {##2} { } \fp_flag_on:n { invalid_operation } \exp_after:wN \c_nan_fp } @@ -258,7 +260,7 @@ { \cs_set:Npn \@@_division_by_zero_o:Nnw ##1##2##3; } { #1 - \@@_error:nffn { zero-div } {##2} { \@@_to_tl:w ##3; } { } + \@@_error:nnfn { zero-div } {##2} { \@@_to_tl:w ##3; } { } \fp_flag_on:n { division_by_zero } \exp_after:wN ##1 } @@ -343,7 +345,7 @@ % \begin{macro}[int, EXP] % { % \@@_invalid_operation:nnw, \@@_invalid_operation_o:Nww, -% \@@_array_invalid_operation_o:nw, +% \@@_invalid_operation_tl_o:nf, % \@@_division_by_zero_o:Nnw, \@@_division_by_zero_o:NNww, % \@@_overflow:w , \@@_underflow:w % } @@ -354,7 +356,7 @@ % \begin{macrocode} \cs_new:Npn \@@_invalid_operation:nnw #1#2#3; { } \cs_new:Npn \@@_invalid_operation_o:Nww #1#2; #3; { } -\cs_new:Npn \@@_array_invalid_operation_o:nw #1 #2 @ { } +\cs_new:Npn \@@_invalid_operation_tl_o:nf #1 #2 { } \cs_new:Npn \@@_division_by_zero_o:Nnw #1#2#3; { } \cs_new:Npn \@@_division_by_zero_o:NNww #1#2#3; #4; { } \cs_new:Npn \@@_overflow:w { } @@ -379,39 +381,15 @@ % \subsection{Errors} % %^^A begin[todo] -% \begin{macro}[int, EXP]{\@@_error:nnnn, \@@_error:nffn} +% \begin{macro}[int, EXP]{\@@_error:nnnn, \@@_error:nnfn, \@@_error:nffn} % \begin{macrocode} \cs_new:Npn \@@_error:nnnn #1 { \__msg_kernel_expandable_error:nnnnn { kernel } { fp - #1 } } -\cs_generate_variant:Nn \@@_error:nnnn { nff } +\cs_generate_variant:Nn \@@_error:nnnn { nnf, nff } % \end{macrocode} % \end{macro} % ^^A end[todo] % -% ^^A todo: move \@@_array_to_clist:w elsewhere. -% \begin{macro}[int, EXP]{\@@_array_to_clist:w} -% \begin{macro}[aux, EXP]{\@@_array_to_clist_i:wwww, \@@_array_to_clist_ii:ww} -% Converts an array of floating point numbers to a comma-list. Does -% not work for empty arrays. -% \begin{macrocode} -\cs_new:Npn \@@_array_to_clist:w #1 @ - { - \@@_array_to_clist_i:wwww ; - #1 - \@@_array_to_clist_ii:ww \s_@@ ; @ - } -\cs_new:Npn \@@_array_to_clist_i:wwww #1; #2 \s_@@ #3; #4 @ - { - #2 - \exp_after:wN \@@_array_to_clist_i:wwww - \tex_romannumeral:D -`0 \@@_to_tl:w \s_@@ #3 ; ; - #4 , ~ #1 @ - } -\cs_new:Npn \@@_array_to_clist_ii:ww #1 ; , ~ , ~ #2 @ {#2} -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \subsection{Messages} % % Some messages. diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx index d6682a661c3..1f5874ca602 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-trig.dtx 3514 2012-03-08 06:14:48Z bruno $ +\GetIdInfo$Id: l3fp-trig.dtx 4151 2012-08-28 11:51:52Z bruno $ {L3 Floating-point trigonometric functions} \documentclass[full]{l3doc} \begin{document} @@ -79,39 +79,25 @@ % %^^A todo: check EXP/rEXP everywhere. % -% \subsection{Inverting a floating point number} -% -% \begin{macro}[int, EXP]{\@@_one_over:w} -% Expects a floating point of the form \cs{s_@@} \ldots{} |;| and -% computes its multiplicative inverse. This is used to compute the -% cotangent function very near $0$. -% \begin{macrocode} -\cs_new_nopar:Npx \@@_one_over:w - { - \exp_not:N \exp_after:wN - \exp_not:c { @@_/_o:ww } - \exp_not:N \c_one_fp - } -% \end{macrocode} -% \end{macro} -% % \subsection{Direct trigonometric functions} % % The approach for all trigonometric functions (sine, cosine, tangent, -% and cotangent) is the same. +% cotangent, cosecant, and secant) is the same. % \begin{itemize} -% \item Filter out special cases ($\pm 0$, $\pm\inf$ and \nan{}). -% \item Keep the sign for later, and work with the absolute value $|x|$ -% of the argument. -% \item For numbers less than $1$, shift the mantissa to convert them to -% fixed point numbers. Very small numbers take a slightly different -% route. -% \item For numbers $\geq 1$, subtract a multiple of $\pi/2$ to bring -% them to the range to $[0, \pi/2]$. -% \item Reduce further to $[0, \pi/4]$ using $\sin x = \cos (\pi/2-x)$. -% \item Use the appropriate power series depending on the octant -% $\lfloor\frac{|x|}{\pi/4}\rfloor \mod 8$, the sign, and the function -% to compute. +% \item Filter out special cases ($\pm 0$, $\pm\inf$ and \nan{}). +% \item Keep the sign for later, and work with the absolute value +% $|x|$ of the argument. +% \item For numbers less than $1$, shift the significand to convert them +% to fixed point numbers. Very small numbers take a slightly +% different route. +% \item For numbers $\geq 1$, subtract a multiple of $\pi/2$ to bring +% them to the range to $[0, \pi/2]$. (This is called argument +% reduction.) +% \item Reduce further to $[0, \pi/4]$ using $\sin x = \cos +% (\pi/2-x)$. +% \item Use the appropriate power series depending on the octant +% $\lfloor\frac{|x|}{\pi/4}\rfloor \mod 8$, the sign, and the +% function to compute. % \end{itemize} % % \subsubsection{Sign and special numbers} @@ -119,23 +105,25 @@ % \begin{macro}[int, EXP]{\@@_sin_o:w} % The sine of $\pm 0$ or \nan{} is the same floating point number. % The sine of $\pm\infty$ raises an invalid operation exception. -% Otherwise, check the exponent, preparing to use -% \cs{@@_sin_series:NNwww} for the calculation, with a sign |#2|, and -% an initial octant of $0$. The question mark is an argument which is -% not used in this case. +% Otherwise, \cs{@@_trig_exponent:NNNNNwn} checks the exponent: if the +% number is tiny, use \cs{@@_trig_epsilon_o:w} which returns +% $\sin\epsilon = \epsilon$. For larger inputs, use the series +% \cs{@@_sin_series:NNwww} after argument reduction. In this second +% case, we will use a sign~|#2|, an initial octant of~$0$, and convert +% the result of the series to a floating point directly, since +% $\sin(x) = \#2 \sin\lvert x\rvert$. % \begin{macrocode} \cs_new:Npn \@@_sin_o:w \s_@@ \@@_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \@@_case_return_same_o:w \or: - \exp_after:wN \@@_trig_exponent:NNNNwn - \exp_after:wN \@@_sin_series:NNwww - \exp_after:wN ? - \exp_after:wN #2 - \exp_after:wN \c_zero - \or: - \@@_case_use:nw { \@@_invalid_operation_o:nw { sin } } + \@@_case_use:nw + { + \@@_trig_exponent:NNNNNwn \@@_trig_epsilon_o:w + \@@_sin_series:NNwww \@@_fixed_to_float:wN #2 \c_zero + } + \or: \@@_case_use:nw { \@@_invalid_operation_o:nw { sin } } \else: \@@_case_return_same_o:w \fi: \s_@@ \@@_chk:w #1#2 @@ -146,27 +134,81 @@ % \begin{macro}[int, EXP]{\@@_cos_o:w} % The cosine of $\pm 0$ is $1$. The cosine of $\pm\infty$ raises an % invalid operation exception. The cosine of \nan{} is itself. -% Otherwise, check the exponent, preparing to use -% \cs{@@_sin_series:NNwww} for the calculation, with a positive sign -% ($0$), and an initial octant of $2$, because $\cos x = \sin ( \pi/2 -% + |x|)$. The question mark is an argument which is not used in this -% case. +% Otherwise, \cs{@@_trig_exponent:NNNNNwn} checks the exponent: if the +% number is tiny, use \cs{@@_trig_epsilon_one_o:w} which returns +% $\cos\epsilon = 1$. For larger inputs, use the same series as for +% sine, but using a positive sign~|0| and with an initial octant +% of~$2$, because $\cos(x) = + \sin(\pi/2 + \lvert x\rvert)$. % \begin{macrocode} \cs_new:Npn \@@_cos_o:w \s_@@ \@@_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \@@_case_return_o:Nw \c_one_fp \or: - \@@_case_use:nw %^^A todo: is that faster than the exp_after route? + \@@_case_use:nw + { + \@@_trig_exponent:NNNNNwn \@@_trig_epsilon_one_o:w + \@@_sin_series:NNwww \@@_fixed_to_float:wN 0 \c_two + } + \or: \@@_case_use:nw { \@@_invalid_operation_o:nw { cos } } + \else: \@@_case_return_same_o:w + \fi: + \s_@@ \@@_chk:w #1#2 + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int, EXP]{\@@_csc_o:w} +% The cosecant of $\pm 0$ is $\pm \infty$ with the same sign, with a +% division by zero exception (see \cs{@@_cot_zero_o:Nnw} defined +% below). The cosecant of $\pm\infty$ raises an invalid operation +% exception. The cosecant of \nan{} is itself. Otherwise, +% \cs{@@_trig_exponent:NNNNNwn} checks the exponent: if the number is +% tiny, use \cs{@@_trig_epsilon_inv_o:w} which returns $\csc\epsilon = +% 1/\epsilon$. For larger inputs, use the same series as for sine, +% using the sign~|#2|, a starting octant of~$0$, and inverting during +% the conversion from the fixed point sine to the floating point +% result, because $\csc(x) = \#2 \big( \sin\lvert x\rvert\big)^{-1}$. +% \begin{macrocode} +\cs_new:Npn \@@_csc_o:w \s_@@ \@@_chk:w #1#2 + { + \if_case:w #1 \exp_stop_f: + \@@_cot_zero_o:Nnw #2 { csc } + \or: + \@@_case_use:nw { - \@@_trig_exponent:NNNNwn - \@@_sin_series:NNwww - ? - 0 - \c_two + \@@_trig_exponent:NNNNNwn \@@_trig_epsilon_inv_o:w + \@@_sin_series:NNwww \@@_fixed_inv_to_float:wN #2 \c_zero } + \or: \@@_case_use:nw { \@@_invalid_operation_o:nw { csc } } + \else: \@@_case_return_same_o:w + \fi: + \s_@@ \@@_chk:w #1#2 + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int, EXP]{\@@_sec_o:w} +% The secant of $\pm 0$ is $1$. The secant of $\pm \infty$ raises an +% invalid operation exception. The secant of \nan{} is itself. +% Otherwise, \cs{@@_trig_exponent:NNNNNwn} checks the exponent: if the +% number is tiny, use \cs{@@_trig_epsilon_one_o:w} which returns +% $\sec\epsilon = 1$. For larger inputs, use the same series as for +% sine, using a positive sign~$0$, a starting octant of~$2$, and +% inverting upon conversion, because $\sec(x) = + 1 / \sin(\pi/2 + +% \lvert x\rvert)$. +% \begin{macrocode} +\cs_new:Npn \@@_sec_o:w \s_@@ \@@_chk:w #1#2 + { + \if_case:w #1 \exp_stop_f: + \@@_case_return_o:Nw \c_one_fp \or: - \@@_case_use:nw { \@@_invalid_operation_o:nw { cos } } + \@@_case_use:nw + { + \@@_trig_exponent:NNNNNwn \@@_trig_epsilon_one_o:w + \@@_sin_series:NNwww \@@_fixed_inv_to_float:wN 0 \c_two + } + \or: \@@_case_use:nw { \@@_invalid_operation_o:nw { sec } } \else: \@@_case_return_same_o:w \fi: \s_@@ \@@_chk:w #1#2 @@ -177,24 +219,25 @@ % \begin{macro}[int, EXP]{\@@_tan_o:w} % The tangent of $\pm 0$ or \nan{} is the same floating point number. % The tangent of $\pm\infty$ raises an invalid operation exception. -% Otherwise, check the exponent, preparing to use -% \cs{@@_tan_series:NNwww} for the calculation, with a positive sign -% ($0$), and an initial octant of $1$, chosen to be distinct from the -% octants for sine and cosine. See \cs{@@_cot_o:w} for an -% explanation of the $0$ argument. +% Otherwise, \cs{@@_trig_exponent:NNNNNwn} checks the exponent: if the +% number is tiny, use \cs{@@_trig_epsilon_o:w} which returns +% $\tan\epsilon = \epsilon$. For larger inputs, use +% \cs{@@_tan_series_o:NNwww} for the calculation after argument +% reduction, with a sign~|#2| and an initial octant of~$1$ (this shift +% is somewhat arbitrary). See \cs{@@_cot_o:w} for an explanation of +% the $0$~argument. % \begin{macrocode} \cs_new:Npn \@@_tan_o:w \s_@@ \@@_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \@@_case_return_same_o:w \or: - \exp_after:wN \@@_trig_exponent:NNNNwn - \exp_after:wN \@@_tan_series:NNwww - \exp_after:wN 0 - \exp_after:wN #2 - \exp_after:wN \c_one - \or: - \@@_case_use:nw { \@@_invalid_operation_o:nw { tan } } + \@@_case_use:nw + { + \@@_trig_exponent:NNNNNwn \@@_trig_epsilon_o:w + \@@_tan_series_o:NNwww 0 #2 \c_one + } + \or: \@@_case_use:nw { \@@_invalid_operation_o:nw { tan } } \else: \@@_case_return_same_o:w \fi: \s_@@ \@@_chk:w #1#2 @@ -203,110 +246,123 @@ % \end{macro} % % \begin{macro}[int, EXP]{\@@_cot_o:w} -% The cotangent of $\pm 0$ is $\pm \infty$ with the same sign, -% produced by \cs{@@_one_over:w}. The cotangent of $\pm\infty$ raises -% an invalid operation exception. The cotangent of \nan{} is itself. -% We use $\cot x = - \tan (\pi/2 + x)$, and the initial octant for the -% tangent was chosen to be $1$, so the octant here starts at $3$. The -% change in sign is obtained by feeding \cs{@@_tan_series:NNwww} two -% signs rather than just the sign of the argument: the first of those -% indicates whether we compute tangent or cotangent. Those signs are -% eventually combined. +% \begin{macro}[aux, EXP]{\@@_cot_zero_o:Nnw} +% The cotangent of $\pm 0$ is $\pm \infty$ with the same sign, with a +% division by zero exception (see \cs{@@_cot_zero_o:Nnw}. The +% cotangent of $\pm\infty$ raises an invalid operation exception. The +% cotangent of \nan{} is itself. We use $\cot x = - \tan (\pi/2 + +% x)$, and the initial octant for the tangent was chosen to be $1$, so +% the octant here starts at $3$. The change in sign is obtained by +% feeding \cs{@@_tan_series_o:NNwww} two signs rather than just the sign +% of the argument: the first of those indicates whether we compute +% tangent or cotangent. Those signs are eventually combined. % \begin{macrocode} \cs_new:Npn \@@_cot_o:w \s_@@ \@@_chk:w #1#2 { \if_case:w #1 \exp_stop_f: - \exp_after:wN \@@_one_over:w - \or: - \exp_after:wN \@@_trig_exponent:NNNNwn - \exp_after:wN \@@_tan_series:NNwww - \exp_after:wN 2 - \exp_after:wN #2 - \exp_after:wN \c_three + \@@_cot_zero_o:Nnw #2 { cot } \or: - \@@_case_use:nw { \@@_invalid_operation_o:nw { cot } } + \@@_case_use:nw + { + \@@_trig_exponent:NNNNNwn \@@_trig_epsilon_inv_o:w + \@@_tan_series_o:NNwww 2 #2 \c_three + } + \or: \@@_case_use:nw { \@@_invalid_operation_o:nw { cot } } \else: \@@_case_return_same_o:w \fi: \s_@@ \@@_chk:w #1#2 } +\cs_new:Npn \@@_cot_zero_o:Nnw #1 #2 #3 \fi: + { + \fi: + \if_meaning:w 0 #1 + \exp_after:wN \@@_division_by_zero_o:Nnw \exp_after:wN \c_inf_fp + \else: + \exp_after:wN \@@_division_by_zero_o:Nnw \exp_after:wN \c_minus_inf_fp + \fi: + {#2} + } % \end{macrocode} % \end{macro} +% \end{macro} % % \subsubsection{Small and tiny arguments} % -% \begin{macro}[aux, EXP]{\@@_trig_exponent:NNNNwn} -% The first four arguments control what trigonometric function we +% \begin{macro}[aux, EXP]{\@@_trig_exponent:NNNNNwn} +% The first five arguments control what trigonometric function we % compute, then follows a normal floating point number. If the -% floating point is smaller than $10^{-8}$, then call the appropriate -% \texttt{_epsilon} auxiliary. Otherwise, call the function |#1|, -% with arguments |#2|, |#3|, the octant, computed in an integer -% expression starting with |#4|, and a fixed point number obtained -% from the floating point number by argument reduction. Numbers less -% than $1$ are converted using \cs{@@_trig_small:w} which simply -% shifts the mantissa, while large numbers need argument reduction. +% floating point is smaller than $10^{-8}$, then call the +% \texttt{_epsilon} auxiliary~|#1|. Otherwise, call the function +% |#2|, with arguments |#3|; |#4|; the octant, computed in an integer +% expression starting with |#5| and stopped by a period; and a fixed +% point number obtained from the floating point number by argument +% reduction. Argument reduction leaves a shift into the integer +% expression for the octant. Numbers less than~$1$ are converted +% using \cs{@@_trig_small:w} which simply shifts the significand, while +% large numbers need argument reduction. % \begin{macrocode} -\cs_new:Npn \@@_trig_exponent:NNNNwn #1#2#3#4 \s_@@ \@@_chk:w 1#5#6 +\cs_new:Npn \@@_trig_exponent:NNNNNwn #1#2#3#4#5 \s_@@ \@@_chk:w 1#6#7 { - \if_int_compare:w #6 > - \c_eight - \exp_after:wN #1 + \if_int_compare:w #7 > - \c_eight \exp_after:wN #2 \exp_after:wN #3 - \int_use:N \__int_eval:w #4 - \if_int_compare:w #6 > \c_zero - \exp_after:wN \@@_trig_large:w \__int_value:w + \exp_after:wN #4 + \int_use:N \__int_eval:w #5 + \if_int_compare:w #7 > \c_zero + \exp_after:wN \@@_trig_large:ww \__int_value:w \else: - \exp_after:wN \@@_trig_small:w \__int_value:w + \exp_after:wN \@@_trig_small:ww \__int_value:w \fi: \else: - \if_case:w #4 - \@@_sin_epsilon:w - \or: \@@_sin_epsilon:w - \or: \@@_cos_epsilon:w - \else: \@@_cot_epsilon:w - \fi: - #5 + \exp_after:wN #1 + \exp_after:wN #6 \fi: - #6 ; + #7 ; } % \end{macrocode} % \end{macro} % % \begin{macro}[aux, EXP] -% {\@@_sin_epsilon:w, \@@_cos_epsilon:w, \@@_cot_epsilon:w} +% {\@@_trig_epsilon_o:w, \@@_trig_epsilon_one_o:w, \@@_trig_epsilon_inv_o:w} % Sine and tangent of tiny numbers give the number itself: the % relative error is less than $5 \cdot 10^{-17}$, which is -% appropriate. Cosine simply gives $1$. Cotangent computes the -% inverse. This is actually slightly wrong because further terms in -% the power series could affect the rounding for cotangent. +% appropriate. Cosine and secant simply give~$1$. Cotangent and +% cosecant compute $1/\epsilon$. This is actually slightly wrong +% because further terms in the power series could affect the rounding +% for cotangent. % \begin{macrocode} -\cs_new:Npn \@@_sin_epsilon:w #1 \fi: #2 \fi: #3 ; - { \fi: \fi: \@@_exp_after_o:w \s_@@ \@@_chk:w 1 #2 {#3} } -\cs_new:Npn \@@_cos_epsilon:w #1 \fi: #2 \fi: #3 ; #4 ; - { \fi: \fi: \exp_after:wN \c_one_fp } -\cs_new:Npn \@@_cot_epsilon:w \fi: #1 \fi: #2 ; - { \fi: \fi: \@@_one_over:w \s_@@ \@@_chk:w 1 #1 {#2} } +\cs_new:Npn \@@_trig_epsilon_o:w #1 #2 ; + { \@@_exp_after_o:w \s_@@ \@@_chk:w 1 #1 {#2} } +\cs_new:Npn \@@_trig_epsilon_one_o:w #1 ; #2 ; + { \exp_after:wN \c_one_fp } +\group_begin: + \char_set_catcode_letter:N / + \cs_new:Npn \@@_trig_epsilon_inv_o:w #1 #2 ; + { + \exp_after:wN \@@_/_o:ww + \c_one_fp + \s_@@ \@@_chk:w 1 #1 {#2} + } +\group_end: % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_trig_small:w, \@@_trig_small_aux:wwNN} +% \begin{macro}[aux, EXP]{\@@_trig_small:ww} % Floating point numbers less than $1$ are converted to fixed point -% numbers by shifting the mantissa. Since we have already filtered -% out numbers less than $10^{-8}$, no digit is lost in converting to -% a fixed point number. +% numbers by prepending a number of zeroes to the significand. Since we +% have already filtered out numbers less than $10^{-8}$, we add at +% most $7$ zeroes, hence no digit is lost in converting to a fixed +% point number. % \begin{macrocode} -\cs_new:Npn \@@_trig_small:w #1; +\cs_new:Npn \@@_trig_small:ww #1; #2#3#4#5; { - \exp_after:wN \exp_after:wN \exp_after:wN \@@_trig_small_aux:wwNN - \prg_replicate:nn { - #1 } { 0 } ; - } -\cs_new:Npn \@@_trig_small_aux:wwNN #1; #2#3#4#5; - { - \@@_pack_twice_four:wNNNNNNNN - \@@_pack_twice_four:wNNNNNNNN - \@@_pack_twice_four:wNNNNNNNN - . - ; - #1#2#3#4#5 0000 0000; + \exp_after:wN \@@_pack_twice_four:wNNNNNNNN + \exp_after:wN \@@_pack_twice_four:wNNNNNNNN + \exp_after:wN \@@_pack_twice_four:wNNNNNNNN + \exp_after:wN . + \exp_after:wN ; + \tex_romannumeral:D -`0 + \prg_replicate:nn { - #1 } { 0 } #2#3#4#5 0000 0000 ; } % \end{macrocode} % \end{macro} @@ -318,10 +374,10 @@ % % \begin{macro}[aux, rEXP] % { -% \@@_trig_large:w, \@@_trig_large_i:www, -% \@@_trig_large_ii:wnnnnnn, \@@_trig_large_break:w +% \@@_trig_large:ww, \@@_trig_large_i:www, +% \@@_trig_large_ii_o:wnnnn, \@@_trig_large_break:w % } -% We shift the mantissa by one digit at a time, subtracting a multiple +% We shift the significand by one digit at a time, subtracting a multiple % of $2\pi$ at each step. We use a value of $2\pi$ rounded up, % consistent with the choice of \cs{c_pi_fp}. This is not quite % correct from an accuracy perspective, but has the nice property that @@ -333,98 +389,82 @@ % non-negative integer). The subtraction has a form similar to our % usual multiplications (see \pkg{l3fp-basics} or % \pkg{l3fp-extended}). Once the exponent reaches $0$, we are done -% subtracting $2\pi$, and we call \cs{@@_trig_octant_loop:nw} to do +% subtracting $2\pi$, and we call \cs{@@_trig_octant_loop:nnnnnw} to do % the reduction by $\pi/2$. % \begin{macrocode} -\cs_new:Npn \@@_trig_large:w #1; #2#3; +\cs_new:Npn \@@_trig_large:ww #1; #2#3; { \@@_trig_large_i:www #2; #3 ; #1; } \cs_new:Npn \@@_trig_large_i:www #1; #2; #3; { \if_meaning:w 0 #3 \@@_trig_large_break:w \fi: - \exp_after:wN \@@_trig_large_ii:wnnnnnn + \exp_after:wN \@@_trig_large_ii_o:wnnnn \int_use:N \__int_eval:w ( #1 - 3141 ) / 6283 ; - {#1} #2; + {#1} #2 + \exp_after:wN ; \int_use:N \__int_eval:w \c_minus_one + #3; } -\cs_new:Npn \@@_trig_large_ii:wnnnnnn #1; #2#3#4#5; +\cs_new:Npn \@@_trig_large_ii_o:wnnnn #1; #2#3#4#5 { \exp_after:wN \@@_trig_large_i:www - \int_use:N \__int_eval:w -5 0000 + #20 - #1*62831 - \exp_after:wN \@@_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 + #30 - #1*8530 - \exp_after:wN \@@_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 + #40 - #1*7179 - \exp_after:wN \@@_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 5 0000 0000 + #50 - #1*5880 - \exp_after:wN ; + \int_use:N \__int_eval:w \c_@@_leading_shift_int + #20 - #1*62831 + \exp_after:wN \@@_pack:NNNNNw + \int_use:N \__int_eval:w \c_@@_middle_shift_int + #30 - #1*8530 + \exp_after:wN \@@_pack:NNNNNw + \int_use:N \__int_eval:w \c_@@_middle_shift_int + #40 - #1*7179 + \exp_after:wN \@@_pack:NNNNNw + \int_use:N \__int_eval:w \c_@@_trailing_shift_int + #50 - #1*5880 \exp_after:wN ; } \cs_new:Npn \@@_trig_large_break:w \fi: #1; #2; - { \fi: \@@_trig_octant_loop:nw #2 {0000} {0000} ; } + { \fi: \@@_trig_octant_loop:nnnnnw #2 {0000} {0000} ; } % \end{macrocode} % \end{macro} % -%^^A todo: optimize: we don't need 6x4 digits here, only 4x4. -% % \begin{macro}[aux, rEXP] -% { -% \@@_trig_octant_loop:nw, \@@_trig_octant_break:w, -% \@@_trig_octant_neg:w -% } +% {\@@_trig_octant_loop:nnnnnw, \@@_trig_octant_break:w} % We receive a fixed point number as argument. As long as it is -% greater than $1.5707$ (a slight underestimate of $\pi/2$), subtract -% $\pi/2$, and leave |+ \c_two| in the integer expression for the -% octant. Once it becomes smaller, if it is greater than $0.7854$ -% (overestimate of $\pi/4$), then compute $\pi/2 - x$ and increment -% the octant. If it is negative, correct this by changing the sign -% and decrementing the octant (by adding $7$). The result is in all -% cases in the range $[0, 0.7854]$, appropriate for a series -% expansion. +% greater than half of \cs{c_pi_fp}, namely $1.5707963267948970$, +% subtract that fixed-point approximation of $\pi/2$, and leave |+| +% |\c_two| in the integer expression for the octant. Once the argument +% becomes smaller, break the initial loop. If the number is greater +% than $0.7854$ (overestimate of $\pi/4$), then compute $\pi/2 - x$ +% and increment the octant. The result is in all cases in the range +% $[0, 0.7854]$, appropriate for the series expansions. % \begin{macrocode} -\cs_new:Npn \@@_trig_octant_loop:nw #1#2; +\cs_new:Npn \@@_trig_octant_loop:nnnnnw #1#2#3#4#5#6; { - \if_int_compare:w #1 < 15707 \exp_stop_f: + \if_int_compare:w #1#2 < 157079633 \exp_stop_f: + \if_int_compare:w #1#2 = 157079632 \exp_stop_f: + \if_int_compare:w #3#4 > 67948969 \exp_stop_f: + \use_i_ii:nnn + \fi: + \fi: \@@_trig_octant_break:w \fi: + \c_two - \@@_fixed_sub_back:wwN + \@@_fixed_sub:wwn + {#1} {#2} {#3} {#4} {0000} {0000} ; {15707} {9632} {6794} {8970} {0000} {0000} ; - {#1} #2; - \@@_trig_octant_loop:nw + \@@_trig_octant_loop:nnnnnw } -\cs_new:Npn \@@_trig_octant_break:w #1 \fi: + #2#3 #4; #5#6; #7; +\cs_new:Npn \@@_trig_octant_break:w #1 \fi: + #2#3 #4#5; #6; #7; { \fi: - \if_int_compare:w #5 < 7854 \exp_stop_f: - \if_int_compare:w #5 < \c_zero - \exp_after:wN \@@_trig_octant_neg:w - \fi: + \if_int_compare:w #4 < 7854 \exp_stop_f: \exp_after:wN \@@_use_i_until_s:nw \exp_after:wN . \fi: + \c_one - \@@_fixed_sub:wwN - {15707} {9632} {6794} {8970} {0000} {0000} ; - {#5} #6 ; . ; - } -\cs_new:Npn \@@_trig_octant_neg:w #1\fi: #2; #3#4#5#6#7#8; #9 - { - \fi: - + \c_seven - \exp_after:wN \@@_fixed_add_after:NNNNNwN - \int_use:N \__int_eval:w 1 9999 9998 - #30000 - #4 - \exp_after:wN \@@_fixed_add_pack:NNNNNwN - \int_use:N \__int_eval:w 1 9999 9998 - #5#6 - \exp_after:wN \@@_fixed_add_pack:NNNNNwN - \int_use:N \__int_eval:w 2 0000 0000 - #7#8 ; {#9} ; + \@@_fixed_sub:wwn #6 ; {#4} #5 ; . ; } % \end{macrocode} % \end{macro} % % \subsection{Computing the power series} % -% \begin{macro}[aux, EXP]{\@@_sin_series:NNwww, \@@_sin_series_aux:Nnww} -% Here we receive an unused |?|, a \meta{sign} ($0$ or $2$), a +% \begin{macro}[aux, EXP]{\@@_sin_series:NNwww, \@@_sin_series_aux:NNnww} +% Here we receive a conversion function \cs{@@_fixed_to_float:wN} or +% \cs{@@_fixed_inv_to_float:wN}, a \meta{sign} ($0$ or $2$), a % (non-negative) \meta{octant} delimited by a dot, a \meta{fixed % point} number, and junk delimited by a semicolon. The auxiliary % receives: @@ -448,14 +488,15 @@ % \frac{1}{5!} - x^2 \bigg( \cdots \bigg) \bigg) \bigg) \bigg) % \] % is used. Finally, the fixed point number is converted to a floating -% point number with the given sign, and we check for overflow or -% underflow. %^^A todo: can over/underflow really happen?? +% point number with the given sign, and \cs{@@_sanitize:Nw} checks for +% overflow and underflow. % \begin{macrocode} \cs_new:Npn \@@_sin_series:NNwww #1#2#3 . #4; #5; { \@@_fixed_mul:wwn #4; #4; { - \exp_after:wN \@@_sin_series_aux:Nnww + \exp_after:wN \@@_sin_series_aux:NNnww + \exp_after:wN #1 \__int_value:w \if_int_odd:w \__int_eval:w ( #3 + \c_two ) / \c_four \__int_eval_end: #2 @@ -466,66 +507,81 @@ } #4 ; } -\cs_new:Npn \@@_sin_series_aux:Nnww #1#2 #3; #4; +\cs_new:Npn \@@_sin_series_aux:NNnww #1#2#3 #4; #5; { - \if_int_odd:w \__int_eval:w #2 / \c_two \__int_eval_end: + \if_int_odd:w \__int_eval:w #3 / \c_two \__int_eval_end: \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: - { - \@@_fixed_continue:wn {0000}{0000}{0000}{0001}{5619}{2070}; % 1/18! - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0000}{0000}{0477}{9477}{3324}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0000}{0011}{4707}{4559}{7730}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0000}{2087}{6756}{9878}{6810}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0027}{5573}{1922}{3985}{8907}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{2480}{1587}{3015}{8730}{1587}; - \@@_fixed_mul_sub_back:wwwn #3; {0013}{8888}{8888}{8888}{8888}{8889}; - \@@_fixed_mul_sub_back:wwwn #3; {0416}{6666}{6666}{6666}{6666}{6667}; - \@@_fixed_mul_sub_back:wwwn #3; {5000}{0000}{0000}{0000}{0000}{0000}; - \@@_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000}; + { % 1/18! + \@@_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0001}{5619}{2070}; + #4; {0000}{0000}{0000}{0477}{9477}{3324}; + \@@_fixed_mul_sub_back:wwwn #4; {0000}{0000}{0011}{4707}{4559}{7730}; + \@@_fixed_mul_sub_back:wwwn #4; {0000}{0000}{2087}{6756}{9878}{6810}; + \@@_fixed_mul_sub_back:wwwn #4; {0000}{0027}{5573}{1922}{3985}{8907}; + \@@_fixed_mul_sub_back:wwwn #4; {0000}{2480}{1587}{3015}{8730}{1587}; + \@@_fixed_mul_sub_back:wwwn #4; {0013}{8888}{8888}{8888}{8888}{8889}; + \@@_fixed_mul_sub_back:wwwn #4; {0416}{6666}{6666}{6666}{6666}{6667}; + \@@_fixed_mul_sub_back:wwwn #4; {5000}{0000}{0000}{0000}{0000}{0000}; + \@@_fixed_mul_sub_back:wwwn #4;{10000}{0000}{0000}{0000}{0000}{0000}; } - { - \@@_fixed_continue:wn {0000}{0000}{0000}{0028}{1145}{7254}; % 1/17! - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0000}{0000}{7647}{1637}{3182}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0000}{0160}{5904}{3836}{8216}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0002}{5052}{1083}{8544}{1719}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0275}{5731}{9223}{9858}{9065}; - \@@_fixed_mul_sub_back:wwwn #3; {0001}{9841}{2698}{4126}{9841}{2698}; - \@@_fixed_mul_sub_back:wwwn #3; {0083}{3333}{3333}{3333}{3333}{3333}; - \@@_fixed_mul_sub_back:wwwn #3; {1666}{6666}{6666}{6666}{6666}{6667}; - \@@_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000}; - \@@_fixed_mul:wwn #4; + { % 1/17! + \@@_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0028}{1145}{7254}; + #4; {0000}{0000}{0000}{7647}{1637}{3182}; + \@@_fixed_mul_sub_back:wwwn #4; {0000}{0000}{0160}{5904}{3836}{8216}; + \@@_fixed_mul_sub_back:wwwn #4; {0000}{0002}{5052}{1083}{8544}{1719}; + \@@_fixed_mul_sub_back:wwwn #4; {0000}{0275}{5731}{9223}{9858}{9065}; + \@@_fixed_mul_sub_back:wwwn #4; {0001}{9841}{2698}{4126}{9841}{2698}; + \@@_fixed_mul_sub_back:wwwn #4; {0083}{3333}{3333}{3333}{3333}{3333}; + \@@_fixed_mul_sub_back:wwwn #4; {1666}{6666}{6666}{6666}{6666}{6667}; + \@@_fixed_mul_sub_back:wwwn #4;{10000}{0000}{0000}{0000}{0000}{0000}; + \@@_fixed_mul:wwn #5; } { \exp_after:wN \@@_sanitize:Nw - \exp_after:wN #1 - \int_use:N \__int_eval:w \@@_fixed_to_float:wN + \exp_after:wN #2 + \int_use:N \__int_eval:w #1 } - #1 + #2 } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_tan_series:NNwww, \@@_tan_series_aux:Nnww} -% Similar to \cs{@@_sin_series:NNwww}, but with slightly different -% rules to find the sign. The result is expressed as a ratio of -% polynomials, of the form +% \begin{macro}[aux, EXP]{\@@_tan_series_o:NNwww, \@@_tan_series_aux_o:Nnww} +% Contrarily to \cs{@@_sin_series:NNwww} which received the conversion +% auxiliary as |#1|, here |#1| is $0$ for tangent, and $2$ for +% cotangent. Consider first the case of the tangent. The octant |#3| +% starts at $1$, which means that it is $1$ or $2$ for $\lvert +% x\rvert\in[0,\pi/2]$, it is $3$ or $4$ for $\lvert +% x\rvert\in[\pi/2,\pi]$, and so on: the intervals on which +% $\tan\lvert x\rvert\geq 0$ coincide with those for which $\lfloor +% (|#3| + 1) / 2\rfloor$ is odd. We also have to take into account +% the original sign of $x$ to get the sign of the final result; it is +% straightforward to check that the first \cs{__int_value:w} expansion +% produces $0$ for a positive final result, and $2$ otherwise. A +% similar story holds for $\cot(x)$. +% +% The auxiliary receives the sign, the octant, the square of the +% (reduced) input, and the (reduced) input as arguments. It then +% computes the numerator and denominator of % \[ % \tan(x) \simeq % \frac{x (1 - x^2 (a_1 - x^2 (a_2 - x^2 (a_3 - x^2 (a_4 - x^2 a_5)))))} % {1 - x^2 (b_1 - x^2 (b_2 - x^2 (b_3 - x^2 (b_4 - x^2 b_5))))} . % \] -% The ratio of the two fixed point numbers is converted to a floating -% point number directly to avoid rounding issues. The two fixed -% points may be exchanged before computing the ratio, depending on the -% quadrant. +% The ratio itself is computed by \cs{@@_fixed_div_to_float:ww}, which +% converts it directly to a floating point number to avoid rounding +% issues. For octants~|#2| (really, quadrants) next to a pole of the +% functions, the fixed point numerator and denominator are exchanged +% before computing the ratio. Note that this \cs{if_int_odd:w} test +% relies on the fact that the octant is at least~$1$. % \begin{macrocode} -\cs_new:Npn \@@_tan_series:NNwww #1#2#3. #4; #5; +\cs_new:Npn \@@_tan_series_o:NNwww #1#2#3. #4; #5; { \@@_fixed_mul:wwn #4; #4; { - \exp_after:wN \@@_tan_series_aux:Nnww + \exp_after:wN \@@_tan_series_aux_o:Nnww \__int_value:w \if_int_odd:w \__int_eval:w #3 / \c_two \__int_eval_end: \exp_after:wN \reverse_if:N @@ -535,18 +591,18 @@ } #4 ; } -\cs_new:Npn \@@_tan_series_aux:Nnww #1 #2 #3; #4; +\cs_new:Npn \@@_tan_series_aux_o:Nnww #1 #2 #3; #4; { - \@@_fixed_continue:wn {0000}{0000}{1527}{3493}{0856}{7059}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{0159}{6080}{0274}{5257}{6472}; + \@@_fixed_mul_sub_back:wwwn {0000}{0000}{1527}{3493}{0856}{7059}; + #3; {0000}{0159}{6080}{0274}{5257}{6472}; \@@_fixed_mul_sub_back:wwwn #3; {0002}{4571}{2320}{0157}{2558}{8481}; \@@_fixed_mul_sub_back:wwwn #3; {0115}{5830}{7533}{5397}{3168}{2147}; \@@_fixed_mul_sub_back:wwwn #3; {1929}{8245}{6140}{3508}{7719}{2982}; \@@_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000}; \@@_fixed_mul:wwn #4; { - \@@_fixed_continue:wn {0000}{0007}{0258}{0681}{9408}{4706}; - \@@_fixed_mul_sub_back:wwwn #3; {0000}{2343}{7175}{1399}{6151}{7670}; + \@@_fixed_mul_sub_back:wwwn {0000}{0007}{0258}{0681}{9408}{4706}; + #3; {0000}{2343}{7175}{1399}{6151}{7670}; \@@_fixed_mul_sub_back:wwwn #3; {0019}{2638}{4588}{9232}{8861}{3691}; \@@_fixed_mul_sub_back:wwwn #3; {0536}{6357}{0691}{4344}{6852}{4252}; \@@_fixed_mul_sub_back:wwwn #3; {5263}{1578}{9473}{6842}{1052}{6315}; @@ -574,4 +630,4 @@ % % \PrintChanges % -% \PrintIndex +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx index 059ca848304..5cf7c0ccf91 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx @@ -36,19 +36,22 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp.dtx 4089 2012-08-14 04:52:20Z bruno $ +\GetIdInfo$Id: l3fp.dtx 4151 2012-08-28 11:51:52Z bruno $ {L3 Floating points} %</driver|package> %<*driver> \documentclass[full]{l3doc} \usepackage{amsmath} -\providecommand\nan{\texttt{NaN}} \begin{document} \DocInput{\jobname.dtx} \end{document} %</driver> % \fi % +% ^^A need to provide this inside the file: +% +% \providecommand\nan{\texttt{NaN}} +% % % \title{^^A % The \textsf{l3fp} package: floating points^^A @@ -71,7 +74,7 @@ % % \begin{documentation} % -% A decimal floating point number is one which is stored as a mantissa and a +% A decimal floating point number is one which is stored as a significand and a % separate exponent. The module implements expandably a wide set of % arithmetic, trigonometric, and other operations on decimal floating point % numbers, to be used within floating point expressions. Floating point @@ -87,8 +90,8 @@ % $x\mathop{\&\&}y$, disjunction $x\mathop{\vert\vert}y$, ternary % operator $x\mathop{?}y\mathop{:}z$. % \item Exponentials: $\exp x$, $\ln x$, $x^y$. -% \item Trigonometry: $\sin x$, $\cos x$, $\tan x$, $\cot x$. -% \emph{Not yet:} $\sec x$, $\csc x$. +% \item Trigonometry: $\sin x$, $\cos x$, $\tan x$, $\cot x$, $\sec +% x$, $\csc x$. % \item [\emph{(not yet)}] Inverse trigonometric functions: % $\operatorname{asin} x$, $\operatorname{acos} x$, % $\operatorname{atan} x$, $\operatorname{acot} x$, @@ -181,7 +184,7 @@ % % \section{Setting floating point variables} % -% \begin{function}[updated = 2012-05-08] +% \begin{function}[updated = 2012-05-08, tested = m3fp002] % {\fp_set:Nn, \fp_set:cn, \fp_gset:Nn, \fp_gset:cn} % \begin{syntax} % \cs{fp_set:Nn} \meta{fp~var} \Arg{floating point expression} @@ -190,7 +193,7 @@ % \meta{floating point expression}. % \end{function} % -% \begin{function}[updated = 2012-05-08] +% \begin{function}[updated = 2012-05-08, tested = m3fp002] % { % \fp_set_eq:NN , \fp_set_eq:cN , \fp_set_eq:Nc , \fp_set_eq:cc , % \fp_gset_eq:NN, \fp_gset_eq:cN, \fp_gset_eq:Nc, \fp_gset_eq:cc @@ -202,7 +205,7 @@ % value of \meta{fp~var_2}. % \end{function} % -% \begin{function}[updated = 2012-05-08] +% \begin{function}[updated = 2012-05-08, tested = m3fp002] % {\fp_add:Nn, \fp_add:cn, \fp_gadd:Nn, \fp_gadd:cn} % \begin{syntax} % \cs{fp_add:Nn} \meta{fp~var} \Arg{floating point expression} @@ -211,7 +214,7 @@ % the \meta{fp~var}. % \end{function} % -% \begin{function}[updated = 2012-05-08] +% \begin{function}[updated = 2012-05-08, tested = m3fp002] % {\fp_sub:Nn, \fp_sub:cn, \fp_gsub:Nn, \fp_gsub:cn} % \begin{syntax} % \cs{fp_sub:Nn} \meta{fp~var} \Arg{floating point expression} @@ -222,7 +225,8 @@ % % \section{Using floating point numbers} % -% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08]{\fp_eval:n} +% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08, +% tested = m3fp-convert003]{\fp_eval:n} % \begin{syntax} % \cs{fp_eval:n} \Arg{floating point expression} % \end{syntax} @@ -231,11 +235,12 @@ % exponent. Leading or trailing zeros may be inserted to compensate % for the exponent. Non-significant trailing zeros are trimmed, and % integers are expressed without a decimal separator. The values -% $\pm\infty$ and \texttt{nan} trigger an \enquote{invalid operation} +% $\pm\infty$ and \nan{} trigger an \enquote{invalid operation} % exception. This function is identical to \cs{fp_to_decimal:n}. % \end{function} % -% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08] +% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08, +% tested = m3fp-convert003] % {\fp_to_decimal:N, \fp_to_decimal:c, \fp_to_decimal:n} % \begin{syntax} % \cs{fp_to_decimal:N} \meta{fp~var} @@ -246,11 +251,11 @@ % exponent. Leading or trailing zeros may be inserted to compensate % for the exponent. Non-significant trailing zeros are trimmed, and % integers are expressed without a decimal separator. The values -% $\pm\infty$ and \texttt{nan} trigger an \enquote{invalid operation} +% $\pm\infty$ and \nan{} trigger an \enquote{invalid operation} % exception. % \end{function} % -% \begin{function}[EXP, updated = 2012-07-08] +% \begin{function}[EXP, updated = 2012-07-08, tested = m3fp-convert003] % {\fp_to_dim:N, \fp_to_dim:c, \fp_to_dim:n} % \begin{syntax} % \cs{fp_to_dim:N} \meta{fp~var} @@ -262,11 +267,11 @@ % an additional trailing \texttt{pt}. In particular, the result may % be outside the range $[- 2^{14} + 2^{-17}, 2^{14} - 2^{-17}]$ of % valid \TeX{} dimensions, leading to overflow errors if used as a -% dimension. The values $\pm\infty$ and \texttt{nan} trigger an +% dimension. The values $\pm\infty$ and \nan{} trigger an % \enquote{invalid operation} exception. % \end{function} % -% \begin{function}[EXP, updated = 2012-07-08] +% \begin{function}[EXP, updated = 2012-07-08, tested = m3fp-convert003] % {\fp_to_int:N, \fp_to_int:c, \fp_to_int:n} % \begin{syntax} % \cs{fp_to_int:N} \meta{fp~var} @@ -276,11 +281,12 @@ % result to the closest integer, with ties rounded to an even integer. % The result may be outside the range $[- 2^{31} + 1, 2^{31} - 1]$ of % valid \TeX{} integers, triggering \TeX{} errors if used in an -% integer expression. The values $\pm\infty$ and \texttt{nan} trigger +% integer expression. The values $\pm\infty$ and \nan{} trigger % an \enquote{invalid operation} exception. % \end{function} % -% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08] +% \begin{function}[EXP, added = 2012-05-08, updated = 2012-07-08, +% tested = m3fp-convert003] % {\fp_to_scientific:N, \fp_to_scientific:c, \fp_to_scientific:n} % \begin{syntax} % \cs{fp_to_scientific:N} \meta{fp~var} @@ -292,11 +298,11 @@ % \meta{optional \texttt{-}}\meta{digit}\texttt{.}\meta{15 digits}\texttt{e}\meta{optional sign}\meta{exponent} % \end{quote} % The leading \meta{digit} is non-zero except in the case of $\pm 0$. -% The values $\pm\infty$ and \texttt{nan} trigger an \enquote{invalid +% The values $\pm\infty$ and \nan{} trigger an \enquote{invalid % operation} exception. % \end{function} % -% \begin{function}[EXP, updated = 2012-07-08] +% \begin{function}[EXP, updated = 2012-07-08, tested = m3fp-convert003] % {\fp_to_tl:N, \fp_to_tl:c, \fp_to_tl:n} % \begin{syntax} % \cs{fp_to_tl:N} \meta{fp~var} @@ -310,12 +316,13 @@ % are expressed in a decimal notation without exponent, with trailing % zeros trimmed, and no decimal separator for integer values (see % \cs{fp_to_decimal:n}. Negative numbers start with |-|. The -% special values $\pm 0$, $\pm \inf$ and \texttt{nan} are rendered as +% special values $\pm 0$, $\pm \inf$ and \nan{} are rendered as % |0|, |-0|, \texttt{inf}, \texttt{-inf}, and \texttt{nan} % respectively. % \end{function} % -% \begin{function}[EXP, updated = 2012-07-08]{\fp_use:N, \fp_use:c} +% \begin{function}[EXP, updated = 2012-07-08, tested = m3fp-convert003] +% {\fp_use:N, \fp_use:c} % \begin{syntax} % \cs{fp_use:N} \meta{fp~var} % \end{syntax} @@ -324,13 +331,13 @@ % Leading or trailing zeros may be inserted to compensate for the % exponent. Non-significant trailing zeros are trimmed. Integers are % expressed without a decimal separator. The values $\pm\infty$ and -% \texttt{nan} trigger an \enquote{invalid operation} exception. This +% \nan{} trigger an \enquote{invalid operation} exception. This % function is identical to \cs{fp_to_decimal:N}. % \end{function} % % \section{Floating point conditionals} % -% \begin{function}[EXP, pTF, updated = 2012-05-08] +% \begin{function}[EXP, pTF, updated = 2012-05-08, tested = m3fp002] % {\fp_if_exist:N, \fp_if_exist:c} % \begin{syntax} % \cs{fp_if_exist_p:N} \meta{fp~var} @@ -340,8 +347,8 @@ % check that the \meta{fp~var} really is a floating point variable. % \end{function} % -% \begin{function}[EXP, pTF, updated = 2012-05-08] -% {\fp_compare:nNn, \fp_compare:n} +% \begin{function}[EXP, pTF, updated = 2012-05-08, +% tested = m3fp-logic001]{\fp_compare:nNn, \fp_compare:n} % \begin{syntax} % \cs{fp_compare_p:nNn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} % \cs{fp_compare:nNnTF} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{true code} \Arg{false code} @@ -352,7 +359,7 @@ % \texttt{true} if the \meta{relation} is obeyed. Two floating point % numbers $x$ and $y$ may obey four mutually exclusive relations: % $x<y$, $x=y$, $x>y$, or $x$ and $y$ are not ordered. The latter -% case occurs exactly when one of the operands is \texttt{nan}, and +% case occurs exactly when one of the operands is \nan{}, and % this relations is denoted by the symbol |?|. The \texttt{nNn} % functions support the \meta{relations} |<|, |=|, |>|, and |?|. The % \texttt{n} functions support as a \meta{relation} any combination of @@ -360,9 +367,9 @@ % \meta{relation}), with the restriction that the \meta{relation} may % not start with |?|. Common choices of \meta{relation} include |>=| % (greater or equal), |!=| (not equal), |!?| (comparable). Note that -% a \texttt{nan} is distinct from any value, even another -% \texttt{nan}, hence $x=x$ is not true for a \texttt{nan}. Thus to -% test if a value is \texttt{nan}, use +% a \nan{} is distinct from any value, even another +% \nan{}, hence $x=x$ is not true for a \nan{}. Thus to +% test if a value is \nan{}, use % \begin{verbatim} % \fp_compare:nNnTF { <value> } != { <value> } % { } % <value> is nan @@ -370,6 +377,112 @@ % \end{verbatim} % \end{function} % +% \section{Floating point expression loops} +% +% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% {\fp_do_until:nNnn} +% \begin{syntax} +% \cs{fp_do_until:nNnn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{code} +% \end{syntax} +% Places the \meta{code} in the input stream for \TeX{} to process, +% and then evaluates the relationship between the two \meta{floating +% point expressions} as described for \cs{fp_compare:nNnTF}. If the +% test is \texttt{false} then the \meta{code} will be inserted into +% the input stream again and a loop will occur until the +% \meta{relation} is \texttt{true}. +% \end{function} +% +% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% {\fp_do_while:nNnn} +% \begin{syntax} +% \cs{fp_do_while:nNnn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{code} +% \end{syntax} +% Places the \meta{code} in the input stream for \TeX{} to process, +% and then evaluates the relationship between the two \meta{floating +% point expressions} as described for \cs{fp_compare:nNnTF}. If the +% test is \texttt{true} then the \meta{code} will be inserted into the +% input stream again and a loop will occur until the \meta{relation} +% is \texttt{false}. +% \end{function} +% +% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% {\fp_until_do:nNnn} +% \begin{syntax} +% \cs{fp_until_do:nNnn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{code} +% \end{syntax} +% Evaluates the relationship between the two \meta{floating point +% expressions} as described for \cs{fp_compare:nNnTF}, and then +% places the \meta{code} in the input stream if the \meta{relation} is +% \texttt{false}. After the \meta{code} has been processed by \TeX{} +% the test will be repeated, and a loop will occur until the test is +% \texttt{true}. +% \end{function} +% +% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% {\fp_while_do:nNnn} +% \begin{syntax} +% \cs{fp_while_do:nNnn} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{code} +% \end{syntax} +% Evaluates the relationship between the two \meta{floating point +% expressions} as described for \cs{fp_compare:nNnTF}, and then +% places the \meta{code} in the input stream if the \meta{relation} is +% \texttt{true}. After the \meta{code} has been processed by \TeX{} +% the test will be repeated, and a loop will occur until the test is +% \texttt{false}. +% \end{function} +% +% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% {\fp_do_until:nn} +% \begin{syntax} +% \cs{fp_do_until:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code} +% \end{syntax} +% Places the \meta{code} in the input stream for \TeX{} to process, +% and then evaluates the relationship between the two \meta{floating +% point expressions} as described for \cs{fp_compare:nTF}. If the +% test is \texttt{false} then the \meta{code} will be inserted into +% the input stream again and a loop will occur until the +% \meta{relation} is \texttt{true}. +% \end{function} +% +% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% {\fp_do_while:nn} +% \begin{syntax} +% \cs{fp_do_while:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code} +% \end{syntax} +% Places the \meta{code} in the input stream for \TeX{} to process, +% and then evaluates the relationship between the two \meta{floating +% point expressions} as described for \cs{fp_compare:nTF}. If the +% test is \texttt{true} then the \meta{code} will be inserted into the +% input stream again and a loop will occur until the \meta{relation} +% is \texttt{false}. +% \end{function} +% +% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% {\fp_until_do:nn} +% \begin{syntax} +% \cs{fp_until_do:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code} +% \end{syntax} +% Evaluates the relationship between the two \meta{floating point +% expressions} as described for \cs{fp_compare:nTF}, and then places +% the \meta{code} in the input stream if the \meta{relation} is +% \texttt{false}. After the \meta{code} has been processed by \TeX{} +% the test will be repeated, and a loop will occur until the test is +% \texttt{true}. +% \end{function} +% +% \begin{function}[rEXP, added = 2012-08-16, tested = m3fp-logic003] +% {\fp_while_do:nn} +% \begin{syntax} +% \cs{fp_while_do:nn} \{ \meta{fpexpr_1} \meta{relation} \meta{fpexpr_2} \} \Arg{code} +% \end{syntax} +% Evaluates the relationship between the two \meta{floating point +% expressions} as described for \cs{fp_compare:nTF}, and then places +% the \meta{code} in the input stream if the \meta{relation} is +% \texttt{true}. After the \meta{code} has been processed by \TeX{} +% the test will be repeated, and a loop will occur until the test is +% \texttt{false}. +% \end{function} +% % \section{Some useful constants, and scratch variables} % % \begin{variable}[added = 2012-05-08]{\c_zero_fp, \c_minus_zero_fp} @@ -450,8 +563,8 @@ % (using \cs{fp_trap:nn}) to either produce an error and turn the flag % on, or only turn the flag on, or do nothing at all. % -% \begin{function}[EXP, pTF, added = 2012-08-08, -% tested = m3fp-traps001]{\fp_if_flag_on:n} +% \begin{function}[EXP, pTF, added = 2012-08-08, tested = m3fp-traps001] +% {\fp_if_flag_on:n} % \begin{syntax} % \cs{fp_if_flag_on_p:n} \Arg{exception} % \cs{fp_if_flag_on:nTF} \Arg{exception} \Arg{true code} \Arg{false code} @@ -461,8 +574,8 @@ % \emph{This function is experimental, and may be altered or removed.} % \end{function} % -% \begin{function}[added = 2012-08-08, -% tested = m3fp-traps001]{\fp_flag_off:n} +% \begin{function}[added = 2012-08-08, tested = m3fp-traps001] +% {\fp_flag_off:n} % \begin{syntax} % \cs{fp_flag_off:n} \Arg{exception} % \end{syntax} @@ -471,8 +584,8 @@ % \emph{This function is experimental, and may be altered or removed.} % \end{function} % -% \begin{function}[EXP, added = 2012-08-08, -% tested = m3fp-traps001]{\fp_flag_on:n} +% \begin{function}[EXP, added = 2012-08-08, tested = m3fp-traps001] +% {\fp_flag_on:n} % \begin{syntax} % \cs{fp_flag_on:n} \Arg{exception} % \end{syntax} @@ -506,8 +619,8 @@ % % \section{Viewing floating points} % -% \begin{function}[added = 2012-05-08, updated = 2012-05-27] -% {\fp_show:N, \fp_show:c, \fp_show:n} +% \begin{function}[added = 2012-05-08, updated = 2012-08-14, +% tested = m3fp002]{\fp_show:N, \fp_show:c, \fp_show:n} % \begin{syntax} % \cs{fp_show:N} \meta{fp~var} % \cs{fp_show:n} \Arg{floating point expression} @@ -520,9 +633,6 @@ % % \subsection{Input of floating point numbers} \label{sec:fp-floats} % -% ^^A todo: redoc subsection, write a grammar -% ^^A todo: clarify what has changed compared to the previous l3fp -% % We support four types of floating point numbers: % \begin{itemize} % \item $\pm 0.d_1d_2\ldots{}d_{16} \cdot 10^{n}$, a normal floating @@ -530,7 +640,7 @@ % \leq \ExplSyntaxOn \int_use:N \c__fp_max_exponent_int$; % \item $\pm 0$, zero, with a given sign; % \item $\pm \infty$, infinity, with a given sign; -% \item \texttt{nan}, is \enquote{not a number}, and can be either quiet +% \item \nan{}, is \enquote{not a number}, and can be either quiet % or signalling (\emph{not yet}: this distinction is currently % unsupported); % \item [\emph{(not yet)}] subnormal numbers $\pm 0.d_1d_2\ldots{}d_{16} @@ -543,7 +653,7 @@ % On input, a normal floating point number consists of: % \begin{itemize} % \item \meta{sign}: a possibly empty string of |+| and |-| characters; -% \item \meta{mantissa}: a non-empty string of digits together with zero +% \item \meta{significand}: a non-empty string of digits together with zero % or one dot; % \item \meta{exponent} optionally: the character |e|, followed by a % possibly empty string of |+|~and~|-| tokens, and a non-empty string @@ -551,41 +661,42 @@ % \end{itemize} % The sign of the resulting number is |+| if \meta{sign} contains an % even number of |-|, and |-| otherwise, hence, an empty \meta{sign} -% denotes a non-negative input. The stored mantissa is obtained from -% \meta{mantissa} by omitting the decimal separator and leading zeros, +% denotes a non-negative input. The stored significand is obtained from +% \meta{significand} by omitting the decimal separator and leading zeros, % and rounding to $16$ significant digits, filling with trailing zeros % if necessary. In particular, the value stored is exact if the input -% \meta{mantissa} has at most $16$ digits. The stored \meta{exponent} +% \meta{significand} has at most $16$ digits. The stored \meta{exponent} % is obtained by combining the input \meta{exponent} ($0$ if absent) -% with a shift depending on the position of the mantissa and the number +% with a shift depending on the position of the significand and the number % of leading zeros. % -% A special case arises if the resulting \meta{exponent} is either -% too large or too small to be represented. This results either in an -% overflow (the number is then replaced by $\pm\infty$), or an -% underflow (resulting in $\pm 0$). +% A special case arises if the resulting \meta{exponent} is either too +% large or too small for the floating point number to be +% represented. This results either in an overflow (the number is then +% replaced by $\pm\infty$), or an underflow (resulting in $\pm 0$). % -% The result is thus $\pm 0$ if and only if \meta{mantissa} contains no +% The result is thus $\pm 0$ if and only if \meta{significand} contains no % non-zero digit (\emph{i.e.}, consists only in~|0| characters, and an -% optional |.| character), or there is an underflow. Note that a single -% dot is currently a valid floating point number, equal to~$+0$, but -% that is not guaranteed to remain the case. +% optional |.| character), or if there is an underflow. Note that a +% single dot is currently a valid floating point number, equal to~$+0$, +% but that is not guaranteed to remain true. % % Special numbers are input as follows: % \begin{itemize} % \item \texttt{inf} represents $+\infty$, and can be preceded by any -% \meta{sign}. -% \item \texttt{nan} represents a (quiet) non-number. It can be preceded -% by any sign, but that will be ignored. -% \item Any unrecognisable string will yield a signalling \texttt{nan}. +% \meta{sign}, yielding $\pm\infty$ as appropriate. +% \item \texttt{nan} represents a (quiet) non-number. It can be +% preceded by any sign, but that will be ignored. +% \item Any unrecognizable string triggers an error, and produces a +% \nan{}. % \end{itemize} % -% Note that~|e-1| is not a representation of $10^{-1}$, because it -% could be mistaken with the difference of \enquote{\texttt{e}} and -% $1$. This is consistent with several other programming languages. -% However, in order to avoid confusions, |e-1| is not considered to -% be this difference either. To input the base of natural logarithms, -% use \texttt{exp(1)} or \cs{c_e_fp}. +% Note that~|e-1| is not a representation of $10^{-1}$, because it could +% be mistaken with the difference of \enquote{\texttt{e}} and $1$. This +% is consistent with several other programming languages. However, in +% order to avoid confusions, |e-1| is not considered to be this +% difference either. To input the base of natural logarithms, use +% \texttt{exp(1)} or \cs{c_e_fp}. % % \subsection{Precedence of operators} % \label{sec:fp-precedence} @@ -602,7 +713,7 @@ % \item Binary |+| and |-|. % \item Comparisons |>=|, |!=|, |<?|, \emph{etc}. % \item Logical \texttt{and}, denoted by |&&|. -% \item Logical \texttt{or}, denoted by \verb*+||+. +% \item Logical \texttt{or}, denoted by \verb+||+. % \item Ternary operator |?:| (right associative). % \end{itemize} % The precedence of operations can be overridden using parentheses. @@ -617,14 +728,11 @@ % \subsection{Operations} \label{sec:fp-operations} % % We now present the various operations allowed in floating point -% expressions. When used as a truth value, a floating point expression -% is \texttt{false} if it is $\pm 0$, and \texttt{true} otherwise. +% expressions, from the lowest precedence to the highest. When used as +% a truth value, a floating point expression is \texttt{false} if it is +% $\pm 0$, and \texttt{true} otherwise, including when it is \nan{}. % -% The exceptions listed below are mostly not implemented yet. -% ^^A todo: implement all exceptions already listed. -% ^^A todo: add exceptions to '?:', '!<=>?', etc. -% -% \begin{function}{?:} +% \begin{function}[tested = m3fp-logic002]{?:} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} |?| \meta{operand_2} |:| \meta{operand_3} \} % \end{syntax} @@ -649,7 +757,7 @@ % \end{function} % % \begingroup \catcode`\|=12 -% \begin{function}{TWO BARS} ^^A todo:fix +% \begin{function}[tested = m3fp-logic002]{TWO BARS} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} \texttt{||} \meta{operand_2} \} % \end{syntax} @@ -660,7 +768,7 @@ % \endgroup % % \begingroup \catcode`\&=12 -% \begin{function}{&&} +% \begin{function}[tested = m3fp-logic002]{&&} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} \texttt{&&} \meta{operand_2} \} % \end{syntax} @@ -670,7 +778,7 @@ % \end{function} % \endgroup % -% \begin{function}{\<, =, >, ?} +% \begin{function}[tested = m3fp-logic001]{\<, =, >, ?} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} \meta{comparison} \meta{operand_2} \} % \end{syntax} @@ -680,18 +788,17 @@ % \meta{operand_1} and \meta{operand_2} is true, and $+0$ otherwise. % \end{function} % -% \begin{function}{+, -} +% \begin{function}[tested = m3fp-basics001]{+, -} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} |+| \meta{operand_2} \} % \cs{fp_eval:n} \{ \meta{operand_1} |-| \meta{operand_2} \} % \end{syntax} % Computes the sum or the difference of its two \meta{operands}. The % \enquote{invalid operation} exception occurs for $\infty-\infty$. -% \enquote{Inexact}, \enquote{underflow} and \enquote{overflow} occur -% when appropriate. +% \enquote{Underflow} and \enquote{overflow} occur when appropriate. % \end{function} % -% \begin{function}{*, /} +% \begin{function}[tested = {m3fp-basics002, m3fp-basics003}]{*, /} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} |*| \meta{operand_2} \} % \cs{fp_eval:n} \{ \meta{operand_1} |/| \meta{operand_2} \} @@ -699,12 +806,11 @@ % Computes the product or the ratio of its two \meta{operands}. The % \enquote{invalid operation} exception occurs for $\infty/\infty$, % $0/0$, or $0*\infty$. \enquote{Division by zero} occurs when -% dividing a finite non-zero number by $\pm 0$. The -% \enquote{inexact}, \enquote{underflow} and \enquote{overflow} -% exceptions occur when appropriate. +% dividing a finite non-zero number by $\pm 0$. \enquote{Underflow} +% and \enquote{overflow} occur when appropriate. % \end{function} % -% \begin{function}{+, -, !} +% \begin{function}[tested = m3fp-basics004]{+, -, !} % \begin{syntax} % \cs{fp_eval:n} \{ |+| \meta{operand} \} % \cs{fp_eval:n} \{ |-| \meta{operand} \} @@ -713,116 +819,124 @@ % The unary |+| does nothing, the unary |-| changes the sign of the % \meta{operand}, and |!| \meta{operand} evaluates to $1$ if % \meta{operand} is false and $0$ otherwise (this is the \texttt{not} -% boolean function). +% boolean function). Those operations never raise exceptions. % \end{function} % % \begingroup\catcode`\^=12 -% \begin{function}{**, ^} +% \begin{function}[tested = m3fp-expo001]{**, ^} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} |**| \meta{operand_2} \} % \cs{fp_eval:n} \{ \meta{operand_1} |^| \meta{operand_2} \} % \end{syntax} -% Raises \meta{operand_1} to the power \meta{operand_2}. This operation -% is right associative, hence \texttt{2 ** 2 ** 3} equals -% $2^{2^{3}} = 256$. The \enquote{invalid operation} exception -% occurs if \meta{operand_1} is negative or $-0$, and \meta{operand_2} is -% not an integer, and the result is non-zero. \enquote{Division by -% zero} occurs \emph{not yet}. The \enquote{inexact}, -% \enquote{underflow} and \enquote{overflow} exceptions occur when -% appropriate. +% Raises \meta{operand_1} to the power \meta{operand_2}. This +% operation is right associative, hence \texttt{2 ** 2 ** 3} equals +% $2^{2^{3}} = 256$. The \enquote{invalid operation} exception occurs +% if \meta{operand_1} is negative or $-0$, and \meta{operand_2} is not +% an integer, unless the result is zero (in that case, the sign is +% chosen arbitrarily to be $+0$). \enquote{Division by zero} occurs +% when raising $\pm 0$ to a strictly negative power. +% \enquote{Underflow} and \enquote{overflow} occur when appropriate. % \end{function} % \endgroup % -% \begin{function}{abs} +% \begin{function}[tested = m3fp-basics004]{abs} % \begin{syntax} % \cs{fp_eval:n} \{ |abs(| \meta{fpexpr} |)| \} % \end{syntax} % Computes the absolute value of the \meta{fpexpr}. This function % does not raise any exception beyond those raised when computing its -% operand \meta{fpexpr}. +% operand \meta{fpexpr}. See also \cs{fp_abs:n}. % \end{function} % -% \begin{function}{exp} +% \begin{function}[tested = m3fp-expo001]{exp} % \begin{syntax} % \cs{fp_eval:n} \{ |exp(| \meta{fpexpr} |)| \} % \end{syntax} -% Computes the exponential of the \meta{fpexpr}. The -% \enquote{underflow} and \enquote{overflow} -% exceptions occur when appropriate. +% Computes the exponential of the \meta{fpexpr}. \enquote{Underflow} +% and \enquote{overflow} occur when appropriate. % \end{function} % -% \begin{function}{ln} +% \begin{function}[tested = m3fp-expo001]{ln} % \begin{syntax} % \cs{fp_eval:n} \{ |ln(| \meta{fpexpr} |)| \} % \end{syntax} % Computes the natural logarithm of the \meta{fpexpr}. Negative % numbers have no (real) logarithm, hence the \enquote{invalid % operation} is raised in that case, including for $\ln(-0)$. -% \enquote{Division by zero} occurs when evaluating $\ln(+0)$. The -% \enquote{underflow} and \enquote{overflow} -% exceptions occur when appropriate. +% \enquote{Division by zero} occurs when evaluating $\ln(+0) = +% -\infty$. \enquote{Underflow} and \enquote{overflow} occur when +% appropriate. % \end{function} % -% \begin{function}{max, min} +% \begin{function}[tested = m3fp-logic002]{max, min} % \begin{syntax} % \cs{fp_eval:n} \{ |max(| \meta{fpexpr_1} |,| \meta{fpexpr_2} |,| \ldots{} |)| \} % \cs{fp_eval:n} \{ |min(| \meta{fpexpr_1} |,| \meta{fpexpr_2} |,| \ldots{} |)| \} % \end{syntax} % Evalutes each \meta{fpexpr} and computes the largest (smallest) of % those. If any of the \meta{fpexpr} is a \nan{}, the result is -% \nan{}. +% \nan{}. Those operations do not raise exceptions. % \end{function} % -% \begin{function}{round, round0, round+, round-} +% \begin{function}[tested = {m3fp-round001, m3fp-round002}] +% {round, round0, round+, round-} % \begin{syntax} % \cs{fp_eval:n} \{ |round| \meta{option} |(| \meta{fpexpr} |)| \} % \cs{fp_eval:n} \{ |round| \meta{option} |(| \meta{fpexpr_1} , \meta{fpexpr_2} |)| \} % \end{syntax} -% Rounds \meta{fpexpr_1} to \meta{fpexpr_2} places (this must be an -% integer). When \meta{fpexpr_2} is missing, it is assumed to be $0$, -% \emph{i.e.}, \meta{fpexpr_1} is rounded to an integer. The -% \meta{option} controls the rounding direction: +% Rounds \meta{fpexpr_1} to \meta{fpexpr_2} places. When +% \meta{fpexpr_2} is omitted, it is assumed to be $0$, \emph{i.e.}, +% \meta{fpexpr_1} is rounded to an integer. The \meta{option} +% controls the rounding direction: % \begin{itemize} -% \item by default, the function rounds to the closest allowed number +% \item by default, the operation rounds to the closest allowed number % (rounding ties to even); -% \item with |0|, the function rounds towards $0$, \emph{i.e.}, truncates; -% \item with |+|, the function rounds towards $+\infty$; -% \item with |-|, the function rounds towards $-\infty$. +% \item with |0|, the operation rounds towards $0$, \emph{i.e.}, truncates; +% \item with |+|, the operation rounds towards $+\infty$; +% \item with |-|, the operation rounds towards $-\infty$. % \end{itemize} +% If \meta{fpexpr_2} does not yield an integer less than $10^{8}$ in +% absolute value, then an \enquote{invalid operation} exception is +% raised. \enquote{Overflow} may occur if the result is infinite +% (this cannot happen unless $\meta{fpexpr_2}\string<-9984$). % \end{function} % -% \begin{function}{sin, cos, tan, cot} +% \begin{function}[tested = m3fp-trig001]{sin, cos, tan, cot, csc, sec} % \begin{syntax} % \cs{fp_eval:n} \{ |sin(| \meta{fpexpr} |)| \} % \cs{fp_eval:n} \{ |cos(| \meta{fpexpr} |)| \} % \cs{fp_eval:n} \{ |tan(| \meta{fpexpr} |)| \} % \cs{fp_eval:n} \{ |cot(| \meta{fpexpr} |)| \} +% \cs{fp_eval:n} \{ |csc(| \meta{fpexpr} |)| \} +% \cs{fp_eval:n} \{ |sec(| \meta{fpexpr} |)| \} % \end{syntax} -% Computes the sine, cosine, tangent or cotangent of the -% \meta{fpexpr}. The trigonometric functions are undefined for an -% argument of $\pm\infty$, leading to the \enquote{invalid operation} -% exception. Additionally, evaluating tangent or cotangent at one of -% their poles leads to a \enquote{division by zero} exception. Other -% exceptions occur when appropriate. +% Computes the sine, cosine, tangent, cotangent, cosecant, or secant +% of the \meta{fpexpr}. The trigonometric functions are undefined for +% an argument of $\pm\infty$, leading to the \enquote{invalid +% operation} exception. Additionally, evaluating tangent, +% cotangent, cosecant, or secant at one of their poles leads to a +% \enquote{division by zero} exception. \enquote{Underflow} and +% \enquote{overflow} occur when appropriate. % \end{function} % -% \begin{variable}{inf, nan} +% \begin{variable}[tested = m3fp-parse001]{inf, nan} % The special values $+\infty$, $-\infty$, and \nan{} are represented % as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see \cs{c_inf_fp}, % \cs{c_minus_inf_fp} and \cs{c_nan_fp}). % \end{variable} % -% \begin{variable}{pi} +% \begin{variable}[tested = m3fp-parse001]{pi} % The value of $\pi$ (see \cs{c_pi_fp}). % \end{variable} % -% \begin{variable}{deg} +% \begin{variable}[tested = m3fp-parse001]{deg} % The value of $1^{\circ}$ in radians (see \cs{c_one_degree_fp}). % \end{variable} % -% \begin{variable}{em, ex, in, pt, pc, cm, mm, dd, cc, nd, nc, bp, sp} +% \begin{variable}[tested = m3fp-parse001] +% {em, ex, in, pt, pc, cm, mm, dd, cc, nd, nc, bp, sp} % \newcommand{\unit}[1]{\text{\texttt{#1}}} -% Those units of measurement are equal to their values in \texttt{pt}, +% Those units of measurement are equal to their values in \unit{pt}, % namely % \begin{align*} % 1 \unit{in} & = 72.27 \unit{pt} \\ @@ -837,16 +951,17 @@ % 1 \unit{bp} & = \frac{1}{72} \unit{in} = 1.00375 \unit{pt} \\ % 1 \unit{sp} & = 2^{-16} \unit{pt} = 1.52587890625e-5 \unit{pt}. % \end{align*} -% The values of the (font-dependent) units \texttt{em} and \texttt{ex} -% are gathered from \TeX{} when the surrounding floating point -% expression is evaluated. +% The values of the (font-dependent) units \unit{em} and \unit{ex} are +% gathered from \TeX{} when the surrounding floating point expression +% is evaluated. % \end{variable} % -% \begin{variable}{true, false} +% \begin{variable}[tested = m3fp-parse001]{true, false} % Other names for $1$ and $+0$. % \end{variable} % -% \begin{function}[EXP, added = 2012-05-08]{\dim_to_fp:n} +% \begin{function}[EXP, added = 2012-05-08, tested = m3fp-convert002] +% {\dim_to_fp:n} % \begin{syntax} % \cs{dim_to_fp:n} \Arg{dimexpr} % \end{syntax} @@ -857,29 +972,18 @@ % where a low precision is acceptable. % \end{function} % -% \begin{function}[EXP, added = 2012-05-14, updated = 2012-07-08]{\fp_abs:n} +% \begin{function}[EXP, added = 2012-05-14, updated = 2012-07-08, +% tested = m3fp-convert003]{\fp_abs:n} % \begin{syntax} % \cs{fp_abs:n} \Arg{floating point expression} % \end{syntax} % Evaluates the \meta{floating point expression} as described for -% \cs{fp_eval:n} and leaves the absolute value of the result in -% the input stream. +% \cs{fp_eval:n} and leaves the absolute value of the result in the +% input stream. This function does not raise any exception beyond +% those raised when evaluating its argument. Within floating point +% expressios, |abs()| can be used. % \end{function} % -% ^^A todo -% ^^A \section{Rounding} -% ^^A -% ^^A This explains how to go from a floating point number to a -% ^^A rounded value for various applications. Perhaps worth coding -% ^^A functionalities up to what siunitx can do on this matter. -% -% ^^A todo -% ^^A \section{Floating points} -% ^^A -% ^^A Here, there may be a discussion of what floating point numbers -% ^^A are, and a list of relevant resources (\emph{e.g.}, some of -% ^^A Kahan's articles), and previous \TeX{} packages. -% % \section{Disclaimer and roadmap} % % The package may break down if: @@ -907,7 +1011,8 @@ % \texttt{any}, and \texttt{xor}? % \item Add \texttt{csc} and \texttt{sec}. % \item Add $\log(x,b)$ for logarithm of $x$ in base $b$. -% \item \texttt{hypot} (Euclidean length) and $\atan(x,y) = \atan(x/y)$, +% \item \texttt{hypot} (Euclidean length) and +% $\operatorname{atan}(x,y) = \operatorname{atan}(x/y)$, % also called \texttt{atan2} in other math packages. % Cartesian-to-polar transform. Other inverse trigonometric functions % \texttt{acos}, \texttt{asin}, \texttt{atan} (one and two arguments). @@ -918,8 +1023,8 @@ % \item Random numbers (pgfmath provides |rnd|, |rand|, |random|), with % seed reset at every \cs{fp_set:Nn}. % \item Factorial (not with |!|), gamma function. -% \item Improve coefficients of \texttt{sin}, \texttt{cos} and -% \texttt{tan}. +% \item Improve coefficients of the \texttt{sin} and \texttt{tan} +% series. % \item Treat upper and lower case letters identically in % identifiers, and ignore underscores. % \item Parse $-3<-2<-1$ as it should, not $(-3<-2)<-1$. @@ -933,6 +1038,10 @@ % % Bugs. (Exclamation points mark important bugs.) % \begin{itemize} +% \item[!] Some functions are not monotonic when they should. For +% instance, $\sin(1-10^{-16})$ is wrongly greater than $\sin(1)$. +% \item Add exceptions to |?:|, |!<=>?|, |&&|, \verb"||", and |!|. +% \item |round| should accept any integer as its second argument. % \item Logarithms of numbers very close to $1$ are inaccurate. % \item \texttt{tan} and \texttt{cot} give very slightly wrong results % for arguments near $10^{-8}$. @@ -952,6 +1061,10 @@ % % Possible optimizations/improvements. % \begin{itemize} +% \item Optimize argument reduction for trigonometric functions: we +% don't need $6\times 4$ digits here, only $4\times 4$. +% \item In subsection~\ref{sec:fp-floats}, write a grammar. +% \item Fix the |TWO BARS| business with the index. % \item It would be nice if the \texttt{parse} auxiliaries for each % operation were set up in the corresponding module, rather than % centralizing in \pkg{l3fp-parse}. @@ -974,6 +1087,11 @@ % and \cs{@@_basics_pack_weird_high:NNNNNNNNw} better. Move the % other \texttt{basics_pack} auxiliaries to \pkg{l3fp-aux} under a % better name. +% \item Find out if underflow can really occur for trigonometric +% functions, and redoc as appropriate. +% \item Add bibliography. Some of Kahan's articles, some previous +% \TeX{} fp packages, the international standards,\ldots{} +% \item Also take into account the \enquote{inexact} exception? % \end{itemize} % % \end{documentation} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index d0f7ab46de7..7a176c93588 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3int.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3int.dtx 4121 2012-08-17 01:36:30Z bruno $ {L3 Integers} %</driver|package> %<*driver> @@ -258,7 +258,7 @@ % \begin{syntax} % \cs{int_sub:Nn} \meta{integer} \Arg{integer expression} % \end{syntax} -% Subtracts the result of the \meta{integer expression} to the +% Subtracts the result of the \meta{integer expression} from the % current content of the \meta{integer}. % \end{function} % @@ -365,36 +365,9 @@ % % \section{Integer expression loops} % -% \begin{function}[rEXP]{\int_do_while:nNnn} -% \begin{syntax} -% \cs{int_do_while:nNnn} -% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} -% \end{syntax} -% Evaluates the relationship between the two \meta{integer expressions} -% as described for \cs{int_compare:nNnTF}, and then places the -% \meta{code} in the input stream if the \meta{relation} is -% \texttt{true}. After the \meta{code} has been processed by \TeX{} the -% test will be repeated, and a loop will occur until the test is -% \texttt{false}. -% \end{function} -% % \begin{function}[rEXP]{\int_do_until:nNnn} % \begin{syntax} -% \cs{int_do_until:nNnn} -% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} -% \end{syntax} -% Evaluates the relationship between the two \meta{integer expressions} -% as described for \cs{int_compare:nNnTF}, and then places the -% \meta{code} in the input stream if the \meta{relation} is -% \texttt{false}. After the \meta{code} has been processed by \TeX{} the -% test will be repeated, and a loop will occur until the test is -% \texttt{true}. -% \end{function} -% -% \begin{function}[rEXP]{\int_until_do:nNnn} -% \begin{syntax} -% \cs{int_until_do:nNnn} -% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} +% \cs{int_do_until:nNnn} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -404,10 +377,9 @@ % \meta{relation} is \texttt{true}. % \end{function} % -% \begin{function}[rEXP]{\int_while_do:nNnn} +% \begin{function}[rEXP]{\int_do_while:nNnn} % \begin{syntax} -% \cs{int_while_do:nNnn} \ -% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} +% \cs{int_do_while:nNnn} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -417,38 +389,35 @@ % \meta{relation} is \texttt{false}. % \end{function} % -% \begin{function}[rEXP]{\int_do_while:nn} +% \begin{function}[rEXP]{\int_until_do:nNnn} % \begin{syntax} -% \cs{int_do_while:nn} -% ~~\{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \cs{int_until_do:nNnn} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{integer expressions} -% as described for \cs{int_compare:nTF}, and then places the +% as described for \cs{int_compare:nNnTF}, and then places the % \meta{code} in the input stream if the \meta{relation} is -% \texttt{true}. After the \meta{code} has been processed by \TeX{} the +% \texttt{false}. After the \meta{code} has been processed by \TeX{} the % test will be repeated, and a loop will occur until the test is -% \texttt{false}. +% \texttt{true}. % \end{function} % -% \begin{function}[rEXP]{\int_do_until:nn} +% \begin{function}[rEXP]{\int_while_do:nNnn} % \begin{syntax} -% \cs{int_do_until:nn} -% ~~\{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \cs{int_while_do:nNnn} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{integer expressions} -% as described for \cs{int_compare:nTF}, and then places the +% as described for \cs{int_compare:nNnTF}, and then places the % \meta{code} in the input stream if the \meta{relation} is -% \texttt{false}. After the \meta{code} has been processed by \TeX{} the +% \texttt{true}. After the \meta{code} has been processed by \TeX{} the % test will be repeated, and a loop will occur until the test is -% \texttt{true}. +% \texttt{false}. % \end{function} % -% \begin{function}[rEXP]{\int_until_do:nn} +% \begin{function}[rEXP]{\int_do_until:nn} % \begin{syntax} -% \cs{int_until_do:nn} -% ~~\{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \cs{int_do_until:nn} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} % \end{syntax} -% Places the \meta{code} in the input stream for \TeX\ to process, and +% Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two % \meta{integer expressions} as described for \cs{int_compare:nTF}. % If the test is \texttt{false} then the \meta{code} will be inserted @@ -456,10 +425,9 @@ % \meta{relation} is \texttt{true}. % \end{function} % -% \begin{function}[rEXP]{\int_while_do:nn} +% \begin{function}[rEXP]{\int_do_while:nn} % \begin{syntax} -% \cs{int_while_do:nn} \ -% ~~\{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \cs{int_do_while:nn} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -469,6 +437,30 @@ % \meta{relation} is \texttt{false}. % \end{function} % +% \begin{function}[rEXP]{\int_until_do:nn} +% \begin{syntax} +% \cs{int_until_do:nn} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \end{syntax} +% Evaluates the relationship between the two \meta{integer expressions} +% as described for \cs{int_compare:nTF}, and then places the +% \meta{code} in the input stream if the \meta{relation} is +% \texttt{false}. After the \meta{code} has been processed by \TeX{} the +% test will be repeated, and a loop will occur until the test is +% \texttt{true}. +% \end{function} +% +% \begin{function}[rEXP]{\int_while_do:nn} +% \begin{syntax} +% \cs{int_while_do:nn} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \end{syntax} +% Evaluates the relationship between the two \meta{integer expressions} +% as described for \cs{int_compare:nTF}, and then places the +% \meta{code} in the input stream if the \meta{relation} is +% \texttt{true}. After the \meta{code} has been processed by \TeX{} the +% test will be repeated, and a loop will occur until the test is +% \texttt{false}. +% \end{function} +% % \section{Integer step functions} % % \begin{function}[added = 2012-06-04, updated = 2012-06-29, rEXP] @@ -1508,11 +1500,11 @@ } \cs_new:Npn \int_until_do:nNnn #1#2#3#4 { - \int_compare:nNnF {#1} #2 {#3} - { - #4 - \int_until_do:nNnn {#1} #2 {#3} {#4} - } + \int_compare:nNnF {#1} #2 {#3} + { + #4 + \int_until_do:nNnn {#1} #2 {#3} {#4} + } } \cs_new:Npn \int_do_while:nNnn #1#2#3#4 { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index 5d690ced2cf..a1e30326917 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3msg.dtx 4077 2012-08-10 23:30:52Z bruno $ +\GetIdInfo$Id: l3msg.dtx 4147 2012-08-28 10:27:33Z bruno $ {L3 Messages} %</driver|package> %<*driver> @@ -722,8 +722,9 @@ % formatting. Used in messages which print complex variable contents % completely. % \end{function} -% -% \begin{function}{\__msg_show_variable:Nnn, \__msg_show_variable:Nnx} +% +% \begin{function}[updated = 2012-08-14] +% {\__msg_show_variable:Nnn, \__msg_show_variable:Nnx} % \begin{syntax} % \cs{__msg_show_variable:Nnn} \meta{variable} \Arg{type} \Arg{formatted content} % \end{syntax} @@ -731,8 +732,10 @@ % in the terminal. The \meta{formatted content} will typically be generated % by \texttt{x}-type expansion using the \cs{__msg_show_variable:Nnx} variant: % the nature of the formatting is dependent on the calling module. +% The \meta{formatted content} must be a string, either empty or +% containing |>|; everything until the first |>| will be removed. % \end{function} -% +% % \begin{function}{\__msg_show_variable:n, \__msg_show_variable:x} % \begin{syntax} % \cs{__msg_show_variable:n} \Arg{formatted string} @@ -742,7 +745,7 @@ % and the part of \meta{formatted string} before the first |>| is % removed. Failure to do so causes low-level \TeX{} errors. % \end{function} -% +% % \begin{function} % {\__msg_show_item:n, \__msg_show_item:nn, \__msg_show_item_unbraced:nn} % \begin{syntax} @@ -752,7 +755,7 @@ % Auxiliary functions used within the argument of % \cs{__msg_show_variable:Nnx} to format variable items correctly for % display. The \cs{__msg_show_item:n} version is used for simple lists, -% the \cs{__msg_show_item:nn} and \cs{__msg_show_item_ubraced:nn} versions +% the \cs{__msg_show_item:nn} and \cs{__msg_show_item_unbraced:nn} versions % for key--value like data structures. % \end{function} % @@ -1815,7 +1818,7 @@ \c_msg_coding_error_text_tl Code-level~functions~must~contain~':'~to~separate~the~ argument~specification~from~the~function~name.~This~is~ - needed~when~defining~conditionals~or~when~building~a~ + needed~when~defining~conditionals~or~variants,~or~when~building~a~ parameter~text~from~the~number~of~arguments~of~the~function. } \@@_kernel_new:nnnn { kernel } { protected-predicate } @@ -1854,6 +1857,14 @@ with~a~signature~starting~with~'#1',~but~that~is~longer~than~ the~signature~(part~after~the~colon)~of~'#2'. } +\@@_kernel_new:nnnn { kernel } { invalid-variant } + { Variant~form~'#1'~invalid~for~base~form~'#2'. } + { + \c_msg_coding_error_text_tl + LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~ + with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~ + from~type~'#3'~to~type~'#4'. + } % \end{macrocode} % % Some errors only appear in expandable settings, @@ -2027,10 +2038,10 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_show_variable:Nnn, \@@_show_variable:Nnn} +% \begin{macro}[int]{\@@_show_variable:Nnn, \@@_show_variable:Nnx} % \begin{macro}[int]{\@@_show_variable:n, \@@_show_variable:x} % \begin{macro}[aux,EXP]{\@@_show_variable:w} -% The arguments of \cs{@@_show_variable:Nnn} are +% The arguments of \cs{@@_show_variable:Nnx} are % \begin{itemize} % \item The \meta{variable} to be shown. % \item The \texttt{TF} emptiness conditional for that type of variables. @@ -2050,7 +2061,7 @@ \cs_if_exist:NTF #1 { \@@_term:nnn { LaTeX / kernel } { show- #2 } {#1} - \@@_show_variable:x {#3} + \@@_show_variable:x { \tl_to_str:n {#3} } } { \@@_kernel_error:nnx { kernel } { variable-not-defined } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index 0db3e319bb2..0c81f7f9951 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3prg.dtx 4061 2012-08-08 15:19:07Z bruno $ +\GetIdInfo$Id: l3prg.dtx 4114 2012-08-16 01:57:02Z bruno $ {L3 Control structures} %</driver|package> %<*driver> @@ -282,8 +282,8 @@ % % \begin{function}[EXP,pTF]{\bool_if:N, \bool_if:c} % \begin{syntax} -% \cs{bool_if_p:N} \Arg{boolean} -% \cs{bool_if:NTF} \Arg{boolean} \Arg{true code} \Arg{false code} +% \cs{bool_if_p:N} \meta{boolean} +% \cs{bool_if:NTF} \meta{boolean} \Arg{true code} \Arg{false code} % \end{syntax} % Tests the current truth of \meta{boolean}, and continues expansion % based on this result. @@ -406,11 +406,33 @@ % % \section{Logical loops} % -% Loops using either boolean expressions or stored boolean values. +% Loops using either boolean expressions or stored boolean values. +% +% \begin{function}[rEXP]{\bool_do_until:Nn, \bool_do_until:cn} +% \begin{syntax} +% \cs{bool_do_until:Nn} \meta{boolean} \Arg{code} +% \end{syntax} +% Places the \meta{code} in the input stream for \TeX{} to process, +% and then checks the logical value of the \meta{boolean}. If it is +% \texttt{false} then the \meta{code} will be inserted into the input +% stream again and the process will loop until the \meta{boolean} is +% \texttt{true}. +% \end{function} +% +% \begin{function}[rEXP]{\bool_do_while:Nn, \bool_do_while:cn} +% \begin{syntax} +% \cs{bool_do_while:Nn} \meta{boolean} \Arg{code} +% \end{syntax} +% Places the \meta{code} in the input stream for \TeX{} to process, +% and then checks the logical value of the \meta{boolean}. If it is +% \texttt{true} then the \meta{code} will be inserted into the input +% stream again and the process will loop until the \meta{boolean} is +% \texttt{false}. +% \end{function} % % \begin{function}[rEXP]{\bool_until_do:Nn, \bool_until_do:cn} % \begin{syntax} -% \cs{bool_until_do:Nn} \Arg{boolean} \Arg{code} +% \cs{bool_until_do:Nn} \meta{boolean} \Arg{code} % \end{syntax} % This function firsts checks the logical value of the \meta{boolean}. % If it is \texttt{false} the \meta{code} is placed in the input stream @@ -421,7 +443,7 @@ % % \begin{function}[rEXP]{\bool_while_do:Nn, \bool_while_do:cn} % \begin{syntax} -% \cs{bool_while_do:Nn} \Arg{boolean} \Arg{code} +% \cs{bool_while_do:Nn} \meta{boolean} \Arg{code} % \end{syntax} % This function firsts checks the logical value of the \meta{boolean}. % If it is \texttt{true} the \meta{code} is placed in the input stream @@ -430,6 +452,30 @@ % until the \meta{boolean} is \texttt{false}. % \end{function} % +% \begin{function}[rEXP, updated = 2012-07-08]{\bool_do_until:nn} +% \begin{syntax} +% \cs{bool_do_until:nn} \Arg{boolean expression} \Arg{code} +% \end{syntax} +% Places the \meta{code} in the input stream for \TeX{} to process, +% and then checks the logical value of the \meta{boolean expression} +% as described for \cs{bool_if:nTF}. If it is \texttt{false} then the +% \meta{code} will be inserted into the input stream again and the +% process will loop until the \meta{boolean expression} evaluates to +% \texttt{true}. +% \end{function} +% +% \begin{function}[rEXP, updated = 2012-07-08]{\bool_do_while:nn} +% \begin{syntax} +% \cs{bool_do_while:nn} \Arg{boolean expression} \Arg{code} +% \end{syntax} +% Places the \meta{code} in the input stream for \TeX{} to process, +% and then checks the logical value of the \meta{boolean expression} +% as described for \cs{bool_if:nTF}. If it is \texttt{true} then the +% \meta{code} will be inserted into the input stream again and the +% process will loop until the \meta{boolean expression} evaluates to +% \texttt{false}. +% \end{function} +% % \begin{function}[rEXP, updated = 2012-07-08]{\bool_until_do:nn} % \begin{syntax} % \cs{bool_until_do:nn} \Arg{boolean expression} \Arg{code} @@ -789,7 +835,7 @@ % % \begin{macro}{\bool_show:N, \bool_show:c, \bool_show:n} % Show the truth value of the boolean, as \texttt{true} or -% \texttt{false}. We use \cs{__msg_show_variable:x} to get a better output; +% \texttt{false}. We use \cs{__msg_show_variable:n} to get a better output; % this function requires its argument to start with |>|. % \begin{macrocode} \cs_new_protected:Npn \bool_show:N #1 @@ -804,8 +850,8 @@ \cs_new_protected:Npn \bool_show:n #1 { \bool_if:nTF {#1} - { \__msg_show_variable:x { > true } } - { \__msg_show_variable:x { > false } } + { \__msg_show_variable:n { > true } } + { \__msg_show_variable:n { > false } } } \cs_generate_variant:Nn \bool_show:N { c } % \end{macrocode} @@ -1182,7 +1228,7 @@ % \begin{macrocode} \cs_new:Npn \bool_not_p:n #1 { \bool_if_p:n { ! ( #1 ) } } % \end{macrocode} -% \end{macro} +% \end{macro} % % \begin{macro}{\bool_xor_p:nn} % \UnitTested @@ -1242,7 +1288,7 @@ % \bool_while_do:nn, \bool_do_while:nn , % \bool_until_do:nn, \bool_do_until:nn % } -% \UnitTested +% \UnitTested % Loop functions with the test either before or after the first body % expansion. % \begin{macrocode} @@ -1479,11 +1525,21 @@ % % \begin{macro}[int]{\scan_align_safe_stop:} % When \TeX{} is in the beginning of an align cell (right after the -% \tn{cr}) it is in a somewhat strange mode as it is looking ahead to -% find an \tn{omit} or \tn{noalign} and hasn't looked at the -% preamble yet. Thus an \tn{ifmmode} test will always fail unless -% we insert \cs{scan_stop:} to stop \TeX{}'s scanning ahead. On the other -% hand we don't want to insert a \cs{scan_stop:} every time as that will +% \tn{cr} or |&|) it is in a somewhat strange mode as it is looking +% ahead to find an \tn{omit} or \tn{noalign} and hasn't looked at the +% preamble yet. Thus an \tn{ifmmode} test at the start of an array +% cell (where math mode is introduced by the preamble, not in the cell +% itself) will always fail unless we stop \TeX{} from scanning ahead. +% With \eTeX{}'s first version, this required inserting +% \cs{scan_stop:}, but not in all cases (see below). This is no +% longer needed with a newer \eTeX{}, since protected macros are not +% expanded anymore at the beginning of an alignment cell. We can thus +% use an empty protected macro to stop \TeX{}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \scan_align_safe_stop: { } +% \end{macrocode} +% Let us now explain the earlier version. We don't want to insert +% a \cs{scan_stop:} every time as that will % destroy kerning between letters\footnote{Unless we enforce an extra % pass with an appropriate value of \tn{pretolerance}.} % Unfortunately there is no way to detect if we're in the beginning of @@ -1508,12 +1564,8 @@ % } % } % \end{verbatim} -% However, this is not truly expandable, as there are places where the -% \cs{scan_stop:} ends up in the result. A simpler alternative, which -% can be used selectively, is therefore defined. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \scan_align_safe_stop: { } -% \end{macrocode} +% However, this is not truly expandable, as there are places where the +% \cs{scan_stop:} ends up in the result. % \end{macro} % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index d27c6c48382..cda5912494a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3prop.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3prop.dtx 4092 2012-08-14 14:04:41Z bruno $ {L3 Property lists} %</driver|package> %<*driver> @@ -1026,15 +1026,13 @@ % \subsection{Viewing property lists} % % \begin{macro}[tested = m3show001]{\prop_show:N, \prop_show:c} -% Apply the general \cs{__msg_show_variable:Nnn}. Contrarily +% Apply the general \cs{__msg_show_variable:Nnx}. Contrarily % to sequences and comma lists, we use \cs{__msg_show_item:nn} % to format both the key and the value for each pair. % \begin{macrocode} \cs_new_protected:Npn \prop_show:N #1 { - \__msg_show_variable:Nnn - #1 - { prop } + \__msg_show_variable:Nnx #1 { prop } { \prop_map_function:NN #1 \__msg_show_item:nn } } \cs_generate_variant:Nn \prop_show:N { c } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 38491dd1223..596d6b832cd 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3seq.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3seq.dtx 4092 2012-08-14 14:04:41Z bruno $ {L3 Sequences and stacks} %</driver|package> %<*driver> @@ -1551,13 +1551,11 @@ % % \begin{macro}{\seq_show:N, \seq_show:c} % \UnitTested -% Apply the general \cs{__msg_show_variable:Nnn}. +% Apply the general \cs{__msg_show_variable:Nnx}. % \begin{macrocode} \cs_new_protected:Npn \seq_show:N #1 { - \__msg_show_variable:Nnn - #1 - { seq } + \__msg_show_variable:Nnx #1 { seq } { \seq_map_function:NN #1 \__msg_show_item:n } } \cs_generate_variant:Nn \seq_show:N { c } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index 26797004a54..911fe7571f0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx @@ -36,7 +36,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3skip.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3skip.dtx 4121 2012-08-17 01:36:30Z bruno $ {L3 Dimensions and skips} %</driver|package> %<*driver> @@ -181,7 +181,7 @@ % \begin{syntax} % \cs{dim_sub:Nn} \meta{dimension} \Arg{dimension expression} % \end{syntax} -% Subtracts the result of the \meta{dimension expression} to the +% Subtracts the result of the \meta{dimension expression} from the % current content of the \meta{dimension}. % \end{function} % @@ -292,34 +292,10 @@ % % \section{Dimension expression loops} % -% \begin{function}[rEXP]{\dim_do_while:nNnn} -% \begin{syntax} -% \cs{dim_do_while:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} -% \end{syntax} -% Evaluates the relationship between the two \meta{dimension expressions} -% as described for \cs{dim_compare:nNnTF}, and then places the -% \meta{code} in the input stream if the \meta{relation} is -% \texttt{true}. After the \meta{code} has been processed by \TeX{} the -% test will be repeated, and a loop will occur until the test is -% \texttt{false}. -% \end{function} -% % \begin{function}[rEXP]{\dim_do_until:nNnn} % \begin{syntax} % \cs{dim_do_until:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} % \end{syntax} -% Evaluates the relationship between the two \meta{dimension expressions} -% as described for \cs{dim_compare:nNnTF}, and then places the -% \meta{code} in the input stream if the \meta{relation} is -% \texttt{false}. After the \meta{code} has been processed by \TeX{} the -% test will be repeated, and a loop will occur until the test is -% \texttt{true}. -% \end{function} -% -% \begin{function}[rEXP]{\dim_until_do:nNnn} -% \begin{syntax} -% \cs{dim_until_do:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} -% \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two % \meta{dimension expressions} as described for \cs{dim_compare:nNnTF}. @@ -328,9 +304,9 @@ % \meta{relation} is \texttt{true}. % \end{function} % -% \begin{function}[rEXP]{\dim_while_do:nNnn} +% \begin{function}[rEXP]{\dim_do_while:nNnn} % \begin{syntax} -% \cs{dim_while_do:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} +% \cs{dim_do_while:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -340,33 +316,33 @@ % \meta{relation} is \texttt{false}. % \end{function} % -% \begin{function}[rEXP]{\dim_do_while:nn} +% \begin{function}[rEXP]{\dim_until_do:nNnn} % \begin{syntax} -% \cs{dim_do_while:nn} \{ \meta{dimexpr_1} \meta{relation} \meta{dimexpr_2} \} \Arg{code} +% \cs{dim_until_do:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{dimension expressions} -% as described for \cs{dim_compare:nTF}, and then places the +% as described for \cs{dim_compare:nNnTF}, and then places the % \meta{code} in the input stream if the \meta{relation} is -% \texttt{true}. After the \meta{code} has been processed by \TeX{} the +% \texttt{false}. After the \meta{code} has been processed by \TeX{} the % test will be repeated, and a loop will occur until the test is -% \texttt{false}. +% \texttt{true}. % \end{function} % -% \begin{function}[rEXP]{\dim_do_until:nn} +% \begin{function}[rEXP]{\dim_while_do:nNnn} % \begin{syntax} -% \cs{dim_do_until:nn} \{ \meta{dimexpr_1} \meta{relation} \meta{dimexpr_2} \} \Arg{code} +% \cs{dim_while_do:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{dimension expressions} -% as described for \cs{dim_compare:nTF}, and then places the +% as described for \cs{dim_compare:nNnTF}, and then places the % \meta{code} in the input stream if the \meta{relation} is -% \texttt{false}. After the \meta{code} has been processed by \TeX{} the +% \texttt{true}. After the \meta{code} has been processed by \TeX{} the % test will be repeated, and a loop will occur until the test is -% \texttt{true}. +% \texttt{false}. % \end{function} % -% \begin{function}[rEXP]{\dim_until_do:nn} +% \begin{function}[rEXP]{\dim_do_until:nn} % \begin{syntax} -% \cs{dim_until_do:nn} \{ \meta{dimexpr_1} \meta{relation} \meta{dimexpr_2} \} \Arg{code} +% \cs{dim_do_until:nn} \{ \meta{dimexpr_1} \meta{relation} \meta{dimexpr_2} \} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -376,9 +352,9 @@ % \meta{relation} is \texttt{true}. % \end{function} % -% \begin{function}[rEXP]{\dim_while_do:nn} +% \begin{function}[rEXP]{\dim_do_while:nn} % \begin{syntax} -% \cs{dim_while_do:nn} \{ \meta{dimexpr_1} \meta{relation} \meta{dimexpr_2} \} \Arg{code} +% \cs{dim_do_while:nn} \{ \meta{dimexpr_1} \meta{relation} \meta{dimexpr_2} \} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -388,6 +364,30 @@ % \meta{relation} is \texttt{false}. % \end{function} % +% \begin{function}[rEXP]{\dim_until_do:nn} +% \begin{syntax} +% \cs{dim_until_do:nn} \{ \meta{dimexpr_1} \meta{relation} \meta{dimexpr_2} \} \Arg{code} +% \end{syntax} +% Evaluates the relationship between the two \meta{dimension expressions} +% as described for \cs{dim_compare:nTF}, and then places the +% \meta{code} in the input stream if the \meta{relation} is +% \texttt{false}. After the \meta{code} has been processed by \TeX{} the +% test will be repeated, and a loop will occur until the test is +% \texttt{true}. +% \end{function} +% +% \begin{function}[rEXP]{\dim_while_do:nn} +% \begin{syntax} +% \cs{dim_while_do:nn} \{ \meta{dimexpr_1} \meta{relation} \meta{dimexpr_2} \} \Arg{code} +% \end{syntax} +% Evaluates the relationship between the two \meta{dimension expressions} +% as described for \cs{dim_compare:nTF}, and then places the +% \meta{code} in the input stream if the \meta{relation} is +% \texttt{true}. After the \meta{code} has been processed by \TeX{} the +% test will be repeated, and a loop will occur until the test is +% \texttt{false}. +% \end{function} +% % \section{Using \texttt{dim} expressions and variables} % % \begin{function}[updated = 2011-10-22, EXP]{\dim_eval:n} @@ -548,7 +548,7 @@ % \begin{syntax} % \cs{skip_sub:Nn} \meta{skip} \Arg{skip expression} % \end{syntax} -% Subtracts the result of the \meta{skip expression} to the +% Subtracts the result of the \meta{skip expression} from the % current content of the \meta{skip}. % \end{function} % @@ -769,7 +769,7 @@ % \begin{syntax} % \cs{muskip_sub:Nn} \meta{muskip} \Arg{muskip expression} % \end{syntax} -% Subtracts the result of the \meta{muskip expression} to the +% Subtracts the result of the \meta{muskip expression} from the % current content of the \meta{skip}. % \end{function} % diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty index 6adfc5fed60..edf7566552f 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty @@ -60,8 +60,8 @@ } \def\ExplFileName{expl3} \def\ExplFileDescription{L3 Experimental code bundle wrapper} -\def\ExplFileDate{2012/08/14} -\def\ExplFileVersion{4091} +\def\ExplFileDate{2012/08/29} +\def\ExplFileVersion{4160} \RequirePackage{etex} \reserveinserts{32} \ProvidesExplPackage diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty b/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty index c7c5bcb0eb8..d9dfc41083c 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3basics.dtx 4069 2012-08-08 23:12:57Z bruno $ +\GetIdInfo$Id: l3basics.dtx 4144 2012-08-27 19:37:16Z bruno $ {L3 Basic definitions} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -82,7 +82,10 @@ \tex_let:D \if_int_compare:w \tex_ifnum:D \tex_let:D \__int_to_roman:w \tex_romannumeral:D \tex_let:D \group_insert_after:N \tex_aftergroup:D -\tex_long:D \tex_def:D \exp_args:Nc #1#2 { \exp_after:wN #1 \cs:w #2 \cs_end: } +\tex_long:D \tex_def:D \exp_args:Nc #1#2 + { \exp_after:wN #1 \cs:w #2 \cs_end: } +\tex_long:D \tex_def:D \exp_args:cc #1#2 + { \cs:w #1 \exp_after:wN \cs_end: \cs:w #2 \cs_end: } \tex_def:D \token_to_str:c { \exp_args:Nc \token_to_str:N } \tex_long:D \tex_def:D \cs_meaning:c #1 { @@ -254,7 +257,7 @@ \exp_after:wN \use_ii:nn \fi: { - \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 _p: #5 } #6 + \exp_args:cc { cs_ #2 #3 :Npn } { #4 _p: #5 } #6 { #7 \c_zero \c_true_bool \c_false_bool } } { @@ -264,17 +267,17 @@ } \cs_set_protected:Npn \__prg_generate_T_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7 { - \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 T } #6 + \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 T } #6 { #7 \c_zero \use:n \use_none:n } } \cs_set_protected:Npn \__prg_generate_F_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7 { - \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 F } #6 + \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 F } #6 { #7 \c_zero { } } } \cs_set_protected:Npn \__prg_generate_TF_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7 { - \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 TF } #6 + \exp_args:cc { cs_ #2 #3 :Npn } { #4 : #5 TF } #6 { #7 \c_zero } } \cs_set_protected_nopar:Npn \prg_set_eq_conditional:NNn diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty b/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty index 35d5381e677..18cee384adc 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty @@ -48,7 +48,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3clist.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3clist.dtx 4102 2012-08-15 16:08:27Z bruno $ {L3 Comma separated lists} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -146,7 +146,7 @@ \cs_new_protected_nopar:Npn \clist_put_right:Nn { \__clist_put_right:NNNn \clist_concat:NNN \clist_set:Nn } \cs_new_protected_nopar:Npn \clist_gput_right:Nn - { \__clist_put_right:NNNn \clist_gconcat:NNN \clist_gset:Nn } + { \__clist_put_right:NNNn \clist_gconcat:NNN \clist_set:Nn } \cs_new_protected:Npn \__clist_put_right:NNNn #1#2#3#4 { #2 \l__clist_internal_clist {#4} @@ -419,18 +419,13 @@ } \cs_new_protected:Npn \clist_show:N #1 { - \__msg_show_variable:Nnn - #1 - { clist } + \__msg_show_variable:Nnx #1 { clist } { \clist_map_function:NN #1 \__msg_show_item:n } } \cs_new_protected:Npn \clist_show:n #1 { \clist_set:Nn \l__clist_internal_clist {#1} - \__msg_show_variable:Nnn - \l__clist_internal_clist - { clist } - { \clist_map_function:NN \l__clist_internal_clist \__msg_show_item:n } + \clist_show:N \l__clist_internal_clist } \cs_generate_variant:Nn \clist_show:N { c } \clist_new:N \l_tmpa_clist diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty b/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty index a126e8fd5c4..1b8d88d4761 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty @@ -47,7 +47,7 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3coffins.dtx 4011 2012-07-20 21:02:59Z joseph $ +\GetIdInfo$Id: l3coffins.dtx 4092 2012-08-14 14:04:41Z bruno $ {L3 Coffin code layer} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -807,7 +807,7 @@ { \__coffin_if_exist:NT #1 { - \__msg_show_variable:Nnn #1 { coffins } + \__msg_show_variable:Nnx #1 { coffins } { \prop_map_function:cN { l__coffin_poles_ \__int_value:w #1 _prop } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3color.sty b/Master/texmf-dist/tex/latex/l3kernel/l3color.sty index 1584c055979..12b019250a5 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3color.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3color.sty @@ -47,8 +47,8 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3color.dtx 3991 2012-07-16 19:00:35Z joseph $ - {L3 Experimental colour support} +\GetIdInfo$Id: l3color.dtx 4156 2012-08-29 11:10:09Z joseph $ + {L3 Experimental color support} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \__expl_package_check: diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls b/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls index 111db55e442..641a13ec78c 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls +++ b/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls @@ -52,7 +52,7 @@ \let \fileversionOld \ExplFileVersion \let \filedescriptionOld \ExplFileDescription \RequirePackage{expl3,xparse,calc} -\GetIdInfo$Id: l3doc.dtx 4070 2012-08-09 11:04:46Z joseph $ +\GetIdInfo$Id: l3doc.dtx 4130 2012-08-20 21:30:22Z joseph $ {L3 Experimental documentation class} \ProvidesExplClass {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -71,7 +71,6 @@ \tl_new:N \l__codedoc_macro_tl \int_new:N \l__codedoc_macro_int \int_new:N \g__codedoc_nested_macro_int -\int_new:N \g__codedoc_codeline_int \prop_new:N \g__codedoc_missing_tests_prop \clist_new:N \g_docinput_clist \tl_new:N \l__codedoc_at_replaced_macro_tl @@ -798,7 +797,7 @@ \tl_to_str:N \l__codedoc_at_replaced_macro_tl }] } - \int_gincr:N \g__codedoc_codeline_int + \int_gincr:N \c@CodelineNo \bool_if:NF \l__codedoc_macro_aux_bool { @@ -822,7 +821,7 @@ \exp_args:Nx \DoNotIndex{ \tl_to_str:N \l__codedoc_at_replaced_macro_tl } } - \int_gdecr:N \g__codedoc_codeline_int + \int_gdecr:N \c@CodelineNo \ignorespaces } \tl_clear:N \l__codedoc_macro_tl @@ -1250,7 +1249,7 @@ \immediate\write\@indexfile { \string\indexentry{#1} - { \filesep \int_use:N \g__codedoc_codeline_int } + { \filesep \int_use:N \c@CodelineNo } } } \cs_set_eq:NN \filesep \@empty diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty b/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty index f7a458e9a88..6dceea954ad 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3expan.dtx 4073 2012-08-10 01:33:13Z bruno $ +\GetIdInfo$Id: l3expan.dtx 4149 2012-08-28 10:50:40Z bruno $ {L3 Argument expansion} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -56,6 +56,7 @@ \cs_new:Npn \::: #1 {#1} \cs_new:Npn \::n #1 \::: #2#3 { #1 \::: { #2 {#3} } } \cs_new:Npn \::N #1 \::: #2#3 { #1 \::: {#2#3} } +\cs_new:Npn \::p #1 \::: #2#3# { #1 \::: {#2#3} } \cs_new:Npn \::c #1 \::: #2#3 { \exp_after:wN \__exp_arg_next:Nnn \cs:w #3 \cs_end: {#1} {#2} } \cs_new:Npn \::o #1 \::: #2#3 @@ -109,8 +110,6 @@ { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN {#3} } \cs_new:Npn \exp_args:NNNo #1#2#3#4 { \exp_after:wN #1 \exp_after:wN#2 \exp_after:wN #3 \exp_after:wN {#4} } -\cs_new:Npn \exp_args:cc #1#2 - { \cs:w #1 \exp_after:wN \cs_end: \cs:w #2 \cs_end: } \cs_new:Npn \exp_args:NNc #1#2#3 { \exp_after:wN #1 \exp_after:wN #2 \cs:w # 3\cs_end: } \cs_new:Npn \exp_args:Ncc #1#2#3 @@ -313,80 +312,151 @@ \exp_after:wN #1 \exp_after:wN \__cs_generate_variant:nnNN \exp_after:wN #1 - \etex_detokenize:D {#2} , ? , \q_recursion_stop + \etex_detokenize:D {#2} , \scan_stop: , \q_recursion_stop } \group_begin: - \tex_lccode:D `\Z = `\d \scan_stop: - \tex_lccode:D `\? =`\\ \scan_stop: + \tex_catcode:D `\M = 12 \scan_stop: + \tex_catcode:D `\A = 12 \scan_stop: \tex_catcode:D `\P = 12 \scan_stop: \tex_catcode:D `\R = 12 \scan_stop: - \tex_catcode:D `\O = 12 \scan_stop: - \tex_catcode:D `\T = 12 \scan_stop: - \tex_catcode:D `\E = 12 \scan_stop: - \tex_catcode:D `\C = 12 \scan_stop: - \tex_catcode:D `\Z = 12 \scan_stop: \tex_lowercase:D { \group_end: \cs_new_protected:Npn \__cs_generate_variant:N #1 { - \exp_after:wN \__cs_generate_variant:w - \token_to_meaning:N #1 - \q_mark \cs_new_protected_nopar:Npx - ? PROTECTEZ - \q_mark \cs_new_nopar:Npx - \q_stop + \exp_after:wN \if_meaning:w \exp_not:N #1 #1 + \cs_set_eq:NN \__cs_tmp:w \cs_new_protected_nopar:Npx + \else: + \exp_after:wN \__cs_generate_variant:ww + \token_to_meaning:N #1 MA \q_mark + \q_mark \cs_new_protected_nopar:Npx + PR + \q_mark \cs_new_nopar:Npx + \q_stop + \fi: } - \cs_new_protected:Npn \__cs_generate_variant:w - #1 ? PROTECTEZ #2 \q_mark #3 #4 \q_stop + \cs_new_protected:Npn \__cs_generate_variant:ww #1 MA #2 \q_mark + { \__cs_generate_variant:wwNw #1 } + \cs_new_protected:Npn \__cs_generate_variant:wwNw + #1 PR #2 \q_mark #3 #4 \q_stop { \cs_set_eq:NN \__cs_tmp:w #3 } } \cs_new_protected:Npn \__cs_generate_variant:nnNN #1#2#3#4 - { \__cs_generate_variant:Nnnw #4 {#1}{#2} } + { + \if_meaning:w \c_false_bool #3 + \__msg_kernel_error:nnx { kernel } { missing-colon } + { \token_to_str:c {#1} } + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w + \fi: + \__cs_generate_variant:Nnnw #4 {#1}{#2} + } \cs_new_protected:Npn \__cs_generate_variant:Nnnw #1#2#3#4 , { - \if:w ? #4 + \if_meaning:w \scan_stop: #4 \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: - \exp_after:wN \__cs_generate_variant:NNn - \exp_after:wN #1 - \cs:w - #2 : - \__cs_generate_variant_loop:NwN - ? #3 - \q_mark #4 \__cs_generate_variant_loop_end:w - \q_mark \__cs_generate_variant_loop_error:wnNNnn - \q_stop - \cs_end: - {#4} + \use:x + { + \exp_not:N \__cs_generate_variant:wwNN + \__cs_generate_variant_loop:nNwN { } + #4 + \__cs_generate_variant_loop_end:nwwwNNnn + \q_mark + #3 ~ + { ~ { } \fi: \__cs_generate_variant_loop_long:wNNnn } ~ + { } + \q_stop + \exp_not:N #1 {#2} {#4} + } \__cs_generate_variant:Nnnw #1 {#2} {#3} } -\cs_new:Npn \__cs_generate_variant_loop:NwN #1 #2 \q_mark #3 - { #3 \__cs_generate_variant_loop:NwN #2 \q_mark } -\cs_new:Npn \__cs_generate_variant_loop_end:w #1#2 \q_mark #3 \q_stop {#2} -\cs_new:Npn \__cs_generate_variant_loop_error:wnNNnn - #1 \q_stop \cs_end: #2 #3#4#5#6 +\cs_new:Npn \__cs_generate_variant_loop:nNwN #1#2#3 \q_mark #4 + { + \if:w #2 #4 + \exp_after:wN \__cs_generate_variant_loop_same:w + \else: + \if:w N #4 \else: + \if:w n #4 \else: + \__cs_generate_variant_loop_invalid:NNwNNnn #4#2 + \fi: + \fi: + \fi: + #1 + \prg_do_nothing: + #2 + \__cs_generate_variant_loop:nNwN { } #3 \q_mark + } +\cs_new:Npn \__cs_generate_variant_loop_same:w + #1 \prg_do_nothing: #2#3#4 + { + #3 { #1 \__cs_generate_variant_same:N #2 } + } +\cs_new:Npn \__cs_generate_variant_loop_end:nwwwNNnn + #1#2 \q_mark #3 ~ #4 \q_stop #5#6#7#8 { - \cs_end: {#2} - \__msg_kernel_error:nnxx { kernel } { variant-too-long } - { \tl_to_str:n {#2} } { \token_to_str:N #4 } - #3 #4 {#5} {#6} + \scan_stop: \scan_stop: \fi: + \exp_not:N \q_mark + \exp_not:N \q_stop + \exp_not:N #6 + \exp_not:c { #7 : #8 #1 #3 } + } +\cs_new:Npn \__cs_generate_variant_loop_long:wNNnn #1 \q_stop #2#3#4#5 + { + \exp_not:n + { + \q_mark + \__msg_kernel_error:nnxx { kernel } { variant-too-long } + {#5} { \token_to_str:N #3 } + \use_none:nnnn + \q_stop + #3 + #3 + } + } +\cs_new:Npn \__cs_generate_variant_loop_invalid:NNwNNnn + #1#2 \fi: \fi: \fi: #3 \q_stop #4#5#6#7 + { + \fi: \fi: \fi: + \exp_not:n + { + \q_mark + \__msg_kernel_error:nnxxxx { kernel } { invalid-variant } + {#7} { \token_to_str:N #5 } {#1} {#2} + \use_none:nnnn + \q_stop + #5 + #5 + } + } +\cs_new:Npn \__cs_generate_variant_same:N #1 + { + \if:w N #1 + N + \else: + \if:w p #1 + p + \else: + n + \fi: + \fi: } -\cs_new_protected:Npn \__cs_generate_variant:NNn #1 #2 #3 +\cs_new_protected:Npn \__cs_generate_variant:wwNN + #1 \q_mark #2 \q_stop #3#4 { - \cs_if_free:NTF #2 + #2 + \cs_if_free:NTF #4 { \group_begin: - \__cs_generate_internal_variant:n {#3} - \__cs_tmp:w #2 { \exp_not:c { exp_args:N #3 } \exp_not:N #1 } + \__cs_generate_internal_variant:n {#1} + \__cs_tmp:w #4 { \exp_not:c { exp_args:N #1 } \exp_not:N #3 } \group_end: } { \iow_log:x { - Variant~\token_to_str:N #2~% + Variant~\token_to_str:N #4~% already~defined;~ not~ changing~ it~on~line~% \tex_the:D \tex_inputlineno:D } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3file.sty b/Master/texmf-dist/tex/latex/l3kernel/l3file.sty index c222c3a6358..44e02bdff7c 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3file.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3file.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3file.dtx 4059 2012-08-08 13:12:06Z bruno $ +\GetIdInfo$Id: l3file.dtx 4101 2012-08-15 16:05:33Z bruno $ {L3 File and I/O operations} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -55,6 +55,7 @@ \tl_gset_eq:NN \g_file_current_name_tl \@currname \seq_new:N \g__file_stack_seq \seq_new:N \g__file_record_seq +\tl_new:N \l__file_internal_tl \tl_new:N \l__file_internal_name_tl \seq_new:N \l__file_search_path_seq \seq_new:N \l__file_saved_search_path_seq @@ -141,10 +142,11 @@ \clist_if_exist:NTF \@filelist { \@addtofilelist {#1} } { \seq_gput_right:Nn \g__file_record_seq {#1} } - \seq_gpush:Nn \g__file_stack_seq \g_file_current_name_tl + \seq_gpush:No \g__file_stack_seq \g_file_current_name_tl \tl_gset:Nn \g_file_current_name_tl {#1} \tex_input:D #1 \c_space_tl - \seq_gpop:NN \g__file_stack_seq \g_file_current_name_tl + \seq_gpop:NN \g__file_stack_seq \l__file_internal_tl + \tl_gset_eq:NN \g_file_current_name_tl \l__file_internal_tl } \cs_generate_variant:Nn \__file_input_aux:n { o } \cs_new_protected:Npn \file_path_include:n #1 diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty b/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty index 3918bd5a161..cd23b05bfc1 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty @@ -59,7 +59,7 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp.dtx 4089 2012-08-14 04:52:20Z bruno $ +\GetIdInfo$Id: l3fp.dtx 4151 2012-08-28 11:51:52Z bruno $ {L3 Floating points} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -218,11 +218,15 @@ \int_const:Nn \c__fp_middle_shift_int { 5 0000 * 9999 } \int_const:Nn \c__fp_trailing_shift_int { 5 0000 * 10000 } \cs_new:Npn \__fp_pack:NNNNNw #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} } +\cs_new:Npn \__fp_pack:NNNNNwn #1 #2#3#4#5 #6; #7 + { + #1#2#3#4#5 ; {#7} {#6} } \int_const:Nn \c__fp_big_leading_shift_int { - 15 2374 } \int_const:Nn \c__fp_big_middle_shift_int { 15 2374 * 9999 } \int_const:Nn \c__fp_big_trailing_shift_int { 15 2374 * 10000 } \cs_new:Npn \__fp_pack_big:NNNNNNw #1#2 #3#4#5#6 #7; { + #1#2#3#4#5#6 ; {#7} } +\cs_new:Npn \__fp_pack_big:NNNNNNwn #1#2 #3#4#5#6 #7; #8 + { + #1#2#3#4#5#6 ; {#8} {#7} } \int_const:Nn \c__fp_Bigg_leading_shift_int { - 20 0000 } \int_const:Nn \c__fp_Bigg_middle_shift_int { 20 0000 * 9999 } \int_const:Nn \c__fp_Bigg_trailing_shift_int { 20 0000 * 10000 } @@ -417,7 +421,7 @@ { \cs_set:Npn \__fp_invalid_operation:nnw ##1##2##3; } { #1 - \__fp_error:nffn { invalid } {##2} { \__fp_to_tl:w ##3; } { } + \__fp_error:nnfn { invalid } {##2} { \__fp_to_tl:w ##3; } { } \fp_flag_on:n { invalid_operation } ##1 } @@ -431,11 +435,10 @@ \exp_after:wN \c_nan_fp } \exp_args:Nno \use:n - { \cs_set:Npn \__fp_array_invalid_operation_o:nw ##1##2@ } + { \cs_set:Npn \__fp_invalid_operation_tl_o:nf ##1##2 } { #1 - \__fp_error:nffn { invalid } - {##1} { \__fp_array_to_clist:w ##2 @ } { } + \__fp_error:nnfn { invalid } {##1} {##2} { } \fp_flag_on:n { invalid_operation } \exp_after:wN \c_nan_fp } @@ -452,7 +455,7 @@ { \cs_set:Npn \__fp_division_by_zero_o:Nnw ##1##2##3; } { #1 - \__fp_error:nffn { zero-div } {##2} { \__fp_to_tl:w ##3; } { } + \__fp_error:nnfn { zero-div } {##2} { \__fp_to_tl:w ##3; } { } \fp_flag_on:n { division_by_zero } \exp_after:wN ##1 } @@ -499,7 +502,7 @@ } \cs_new:Npn \__fp_invalid_operation:nnw #1#2#3; { } \cs_new:Npn \__fp_invalid_operation_o:Nww #1#2; #3; { } -\cs_new:Npn \__fp_array_invalid_operation_o:nw #1 #2 @ { } +\cs_new:Npn \__fp_invalid_operation_tl_o:nf #1 #2 { } \cs_new:Npn \__fp_division_by_zero_o:Nnw #1#2#3; { } \cs_new:Npn \__fp_division_by_zero_o:NNww #1#2#3; #4; { } \cs_new:Npn \__fp_overflow:w { } @@ -512,21 +515,7 @@ { \__fp_invalid_operation:nnw { \exp_after:wN \c_nan_fp } } \cs_new:Npn \__fp_error:nnnn #1 { \__msg_kernel_expandable_error:nnnnn { kernel } { fp - #1 } } -\cs_generate_variant:Nn \__fp_error:nnnn { nff } -\cs_new:Npn \__fp_array_to_clist:w #1 @ - { - \__fp_array_to_clist_i:wwww ; - #1 - \__fp_array_to_clist_ii:ww \s__fp ; @ - } -\cs_new:Npn \__fp_array_to_clist_i:wwww #1; #2 \s__fp #3; #4 @ - { - #2 - \exp_after:wN \__fp_array_to_clist_i:wwww - \tex_romannumeral:D -`0 \__fp_to_tl:w \s__fp #3 ; ; - #4 , ~ #1 @ - } -\cs_new:Npn \__fp_array_to_clist_ii:ww #1 ; , ~ , ~ #2 @ {#2} +\cs_generate_variant:Nn \__fp_error:nnnn { nnf, nff } \__msg_kernel_new:nnnn { kernel } { unknown-fpu-exception } { The~FPU~exception~'#1'~is~not~known:~that~trap~will~never~be~triggered. } { @@ -687,7 +676,10 @@ \cs_new:Npn \__fp_round:Nww #1#2 ; #3 ; { \__fp_small_int:wTF #3; { \__fp_round:Nwn #1#2; } - { \__fp_array_invalid_operation_o:nw { round } #2; #3; @ } + { + \__fp_invalid_operation_tl_o:nf + { round } { \__fp_array_to_clist:n { #2; #3; } } + } } \cs_new:Npn \__fp_round:Nwn #1 \s__fp \__fp_chk:w #2#3#4; #5 { @@ -808,7 +800,7 @@ \cs_new:Npn \__fp_type_from_scan:N #1 { \exp_after:wN \__fp_type_from_scan:w - \token_to_str:N #1 \q_mark S--FP \q_mark \q_stop + \token_to_str:N #1 \q_mark S--FP-? \q_mark \q_stop } \cs_new:Npn \__fp_type_from_scan:w #1 S--FP #2 \q_mark #3 \q_stop {#2} } @@ -877,39 +869,26 @@ } \cs_new:Npn \__fp_parse_operand_relax:NN #1#2 { - \__fp_parse_operand_relax_aux:wwnw - #2 \s__fp_mark - { - \__fp_exp_after_o:nw - { - \tex_romannumeral:D -`0 - \exp_after:wN \__fp_parse_infix:NN - \exp_after:wN #1 \tex_romannumeral:D \__fp_parse_expand:w - } - \s__fp - } - \s__fp #2 - { - \__msg_kernel_expandable_error:nn { kernel } { fp-early-end } - \exp_after:wN \c_nan_fp - \tex_romannumeral:D -`0 - \__fp_parse_infix:NN #1 - \s__fp_mark - } - \s__fp_mark - { - \__msg_kernel_expandable_error:nnn - { kernel } { bad-variable } {#2} - \exp_after:wN \c_nan_fp - \tex_romannumeral:D -`0 - \exp_after:wN \__fp_parse_infix:NN - \exp_after:wN #1 - \tex_romannumeral:D \__fp_parse_expand:w - } - \s__fp_mark \s__fp_stop + \cs:w __fp_exp_after \__fp_type_from_scan:N #2 _f:nw \cs_end: + { + \exp_after:wN \__fp_parse_infix:NN + \exp_after:wN #1 \tex_romannumeral:D \__fp_parse_expand:w + } + #2 + } +\cs_new:Npn \__fp_exp_after_mark_f:nw #1 + { + \__msg_kernel_expandable_error:nn { kernel } { fp-early-end } + \exp_after:wN \c_nan_fp + \tex_romannumeral:D -`0 #1 + } +\cs_new:cpn { __fp_exp_after_?_f:nw } #1#2 + { + \__msg_kernel_expandable_error:nnn + { kernel } { bad-variable } {#2} + \exp_after:wN \c_nan_fp + \tex_romannumeral:D -`0 #1 } -\cs_new:Npn \__fp_parse_operand_relax_aux:wwnw - #1 \s__fp #2 \s__fp_mark #3 #4 \s__fp_mark \s__fp_stop { #3 } \cs_new:Npn \__fp_parse_operand_other:NN #1 #2 { \if_int_compare:w @@ -1447,8 +1426,9 @@ \cs:w __fp \__fp_type_from_scan:N #2 + _ #4 \__fp_type_from_scan:N #5 - _ #4 _o:ww + _o:ww \cs_end: #2#3 #5#6 \tex_romannumeral:D -`0 #7 #1 @@ -1504,7 +1484,8 @@ \tex_romannumeral:D -`0 \__fp_parse_infix:NN } } -\tl_map_inline:nn { {abs} {cos} {cot} {exp} {ln} {sin} {tan} } +\tl_map_inline:nn + { {abs} {cos} {cot} {csc} {exp} {ln} {sec} {sin} {tan} } { \cs_new:cpn { __fp_parse_word_#1:N } ##1 { @@ -1600,7 +1581,7 @@ { \token_if_eq_meaning:NNTF #3 \__fp_parse_infix_):N { - \__fp_parse_exp_after_array:wf #2 \s__fp_stop + \__fp_exp_after_array_f:w #2 \s__fp_stop \exp_after:wN \__fp_parse_infix:NN \exp_after:wN #1 \tex_romannumeral:D \__fp_parse_expand:w @@ -1611,13 +1592,13 @@ } } \group_end: -\cs_new:Npn \__fp_parse_exp_after_array:wf #1 +\cs_new:Npn \__fp_exp_after_array_f:w #1 { - \cs:w __fp \__fp_type_from_scan:N #1 _exp_after_f:nw \cs_end: - { \__fp_parse_exp_after_array:wf } + \cs:w __fp_exp_after \__fp_type_from_scan:N #1 _f:nw \cs_end: + { \__fp_exp_after_array_f:w } #1 } -\cs_new:Npn \__fp_stop_exp_after_f:nw #1#2 { } +\cs_new:Npn \__fp_exp_after_stop_f:nw #1#2 { } \cs_new:cpn {__fp_parse_prefix_.:Nw} #1 { \exp_after:wN \__fp_parse_infix_after_operand:NwN @@ -1990,12 +1971,12 @@ \cs_new:Npn \__fp_compare_npos:nwnw #1#2; #3#4; { \if_int_compare:w #1 = #3 \exp_stop_f: - \__fp_compare_mantissa:nnnnnnnn #2 #4 + \__fp_compare_significand:nnnnnnnn #2 #4 \else: \if_int_compare:w #1 < #3 - \fi: 1 \fi: } -\cs_new:Npn \__fp_compare_mantissa:nnnnnnnn #1#2#3#4#5#6#7#8 +\cs_new:Npn \__fp_compare_significand:nnnnnnnn #1#2#3#4#5#6#7#8 { \if_int_compare:w #1#2 = #5#6 \exp_stop_f: \if_int_compare:w #3#4 = #7#8 \exp_stop_f: @@ -2007,6 +1988,62 @@ \if_int_compare:w #1#2 < #5#6 - \fi: 1 \fi: } +\cs_new:Npn \fp_do_until:nn #1#2 + { + #2 + \fp_compare:nF {#1} + { \fp_do_until:nn {#1} {#2} } + } +\cs_new:Npn \fp_do_while:nn #1#2 + { + #2 + \fp_compare:nT {#1} + { \fp_do_while:nn {#1} {#2} } + } +\cs_new:Npn \fp_until_do:nn #1#2 + { + \fp_compare:nF {#1} + { + #2 + \fp_until_do:nn {#1} {#2} + } + } +\cs_new:Npn \fp_while_do:nn #1#2 + { + \fp_compare:nT {#1} + { + #2 + \fp_while_do:nn {#1} {#2} + } + } +\cs_new:Npn \fp_do_until:nNnn #1#2#3#4 + { + #4 + \fp_compare:nNnF {#1} #2 {#3} + { \fp_do_until:nNnn {#1} #2 {#3} {#4} } + } +\cs_new:Npn \fp_do_while:nNnn #1#2#3#4 + { + #4 + \fp_compare:nNnT {#1} #2 {#3} + { \fp_do_while:nNnn {#1} #2 {#3} {#4} } + } +\cs_new:Npn \fp_until_do:nNnn #1#2#3#4 + { + \fp_compare:nNnF {#1} #2 {#3} + { + #4 + \fp_until_do:nNnn {#1} #2 {#3} {#4} + } + } +\cs_new:Npn \fp_while_do:nNnn #1#2#3#4 + { + \fp_compare:nNnT {#1} #2 {#3} + { + #4 + \fp_while_do:nNnn {#1} #2 {#3} {#4} + } + } \cs_new:Npn \__fp_max_o:w #1 @ { \exp_after:wN \__fp_minmax_loop:Nww @@ -2083,7 +2120,7 @@ \__fp_ternary_break_point:n { \exp_after:wN \__fp_ternary_i:NwwN } \exp_after:wN #1 \tex_romannumeral:D -`0 - \__fp_parse_exp_after_array:wf #3 \s__fp_stop + \__fp_exp_after_array_f:w #3 \s__fp_stop \exp_after:wN @ \tex_romannumeral:D \__fp_parse_until:Nw \c_two @@ -2094,7 +2131,7 @@ \exp_after:wN \__fp_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 - \__fp_parse_exp_after_array:wf #3 \s__fp_stop + \__fp_exp_after_array_f:w #3 \s__fp_stop \exp_after:wN #4 \exp_after:wN #1 \fi: @@ -2117,7 +2154,7 @@ \exp_after:wN \__fp_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 - \__fp_parse_exp_after_array:wf #2 \s__fp_stop + \__fp_exp_after_array_f:w #2 \s__fp_stop #4 #1 } \cs_new:Npn \__fp_ternary_ii:NwwN #1#2@#3@#4 @@ -2125,7 +2162,7 @@ \exp_after:wN \__fp_parse_until_test:NwN \exp_after:wN #1 \tex_romannumeral:D -`0 - \__fp_parse_exp_after_array:wf #3 \s__fp_stop + \__fp_exp_after_array_f:w #3 \s__fp_stop #4 #1 } %% File: l3fp-basics.dtx Copyright (C) 2011-2012 The LaTeX3 Project @@ -2273,7 +2310,7 @@ \cs_new:Npn \__fp_add_big_i_o:wNww #1; #2 #3; #4; { \__fp_decimate:nNnnnn {#1} - \__fp_add_mantissa_o:NnnwnnnnN + \__fp_add_significand_o:NnnwnnnnN #4 #3 #2 @@ -2281,34 +2318,34 @@ \cs_new:Npn \__fp_add_big_ii_o:wNww #1; #2 #3; #4; { \__fp_decimate:nNnnnn {#1} - \__fp_add_mantissa_o:NnnwnnnnN + \__fp_add_significand_o:NnnwnnnnN #3 #4 #2 } -\cs_new:Npn \__fp_add_mantissa_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8 +\cs_new:Npn \__fp_add_significand_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8 { - \exp_after:wN \__fp_add_mantissa_test_o:N + \exp_after:wN \__fp_add_significand_test_o:N \int_use:N \__int_eval:w 1#5#6 + #2 - \exp_after:wN \__fp_add_mantissa_pack:NNNNNNN + \exp_after:wN \__fp_add_significand_pack:NNNNNNN \int_use:N \__int_eval:w 1#7#8 + #3 ; #1 } -\cs_new:Npn \__fp_add_mantissa_pack:NNNNNNN #1 #2#3#4#5#6#7 +\cs_new:Npn \__fp_add_significand_pack:NNNNNNN #1 #2#3#4#5#6#7 { \if_meaning:w 2 #1 + \c_one \fi: ; #2 #3 #4 #5 #6 #7 ; } -\cs_new:Npn \__fp_add_mantissa_test_o:N #1 +\cs_new:Npn \__fp_add_significand_test_o:N #1 { \if_meaning:w 2 #1 - \exp_after:wN \__fp_add_mantissa_carry_o:wwwNN + \exp_after:wN \__fp_add_significand_carry_o:wwwNN \else: - \exp_after:wN \__fp_add_mantissa_no_carry_o:wwwNN + \exp_after:wN \__fp_add_significand_no_carry_o:wwwNN \fi: } -\cs_new:Npn \__fp_add_mantissa_no_carry_o:wwwNN +\cs_new:Npn \__fp_add_significand_no_carry_o:wwwNN #1; #2; #3#4 ; #5#6 { \exp_after:wN \__fp_basics_pack_high:NNNNNw @@ -2318,7 +2355,7 @@ + \__fp_round:NNN #6 #4 #5 \exp_after:wN ; } -\cs_new:Npn \__fp_add_mantissa_carry_o:wwwNN +\cs_new:Npn \__fp_add_significand_carry_o:wwwNN #1; #2; #3#4; #5#6 { + \c_one @@ -2527,41 +2564,41 @@ \exp_after:wN #1 \int_use:N \__int_eval:w #4 + #8 - \__fp_mul_mantissa_o:nnnnNnnnn #5 #1 #9 + \__fp_mul_significand_o:nnnnNnnnn #5 #1 #9 } -\cs_new:Npn \__fp_mul_mantissa_o:nnnnNnnnn #1#2#3#4 #5 #6#7#8#9 +\cs_new:Npn \__fp_mul_significand_o:nnnnNnnnn #1#2#3#4 #5 #6#7#8#9 { - \exp_after:wN \__fp_mul_mantissa_test_f:NNN + \exp_after:wN \__fp_mul_significand_test_f:NNN \exp_after:wN #5 \int_use:N \__int_eval:w 99990000 + #1*#6 + - \exp_after:wN \__fp_mul_mantissa_keep:NNNNNw + \exp_after:wN \__fp_mul_significand_keep:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#7 + #2*#6 + - \exp_after:wN \__fp_mul_mantissa_keep:NNNNNw + \exp_after:wN \__fp_mul_significand_keep:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#8 + #2*#7 + #3*#6 + - \exp_after:wN \__fp_mul_mantissa_drop:NNNNNw + \exp_after:wN \__fp_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #1*#9 + #2*#8 + #3*#7 + #4*#6 + - \exp_after:wN \__fp_mul_mantissa_drop:NNNNNw + \exp_after:wN \__fp_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #2*#9 + #3*#8 + #4*#7 + - \exp_after:wN \__fp_mul_mantissa_drop:NNNNNw + \exp_after:wN \__fp_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 99990000 + #3*#9 + #4*#8 + - \exp_after:wN \__fp_mul_mantissa_drop:NNNNNw + \exp_after:wN \__fp_mul_significand_drop:NNNNNw \int_use:N \__int_eval:w 100000000 + #4*#9 ; ; \exp_after:wN ; } -\cs_new:Npn \__fp_mul_mantissa_drop:NNNNNw #1#2#3#4#5 #6; +\cs_new:Npn \__fp_mul_significand_drop:NNNNNw #1#2#3#4#5 #6; { #1#2#3#4#5 ; + #6 } -\cs_new:Npn \__fp_mul_mantissa_keep:NNNNNw #1#2#3#4#5 #6; +\cs_new:Npn \__fp_mul_significand_keep:NNNNNw #1#2#3#4#5 #6; { #1#2#3#4#5 ; #6 ; } -\cs_new:Npn \__fp_mul_mantissa_test_f:NNN #1 #2 #3 +\cs_new:Npn \__fp_mul_significand_test_f:NNN #1 #2 #3 { \if_meaning:w 0 #3 - \exp_after:wN \__fp_mul_mantissa_small_f:NNwwwN + \exp_after:wN \__fp_mul_significand_small_f:NNwwwN \else: - \exp_after:wN \__fp_mul_mantissa_large_f:NwwNNNN + \exp_after:wN \__fp_mul_significand_large_f:NwwNNNN \fi: #1 #3 } -\cs_new:Npn \__fp_mul_mantissa_large_f:NwwNNNN #1 #2; #3; #4#5#6#7; + +\cs_new:Npn \__fp_mul_significand_large_f:NwwNNNN #1 #2; #3; #4#5#6#7; + { \exp_after:wN \__fp_basics_pack_high:NNNNNw \int_use:N \__int_eval:w 1#2 @@ -2572,7 +2609,7 @@ \exp_after:wN #7 \__int_value:w \__fp_round_digit:Nw } -\cs_new:Npn \__fp_mul_mantissa_small_f:NNwwwN #1 #2#3; #4#5; #6; + #7 +\cs_new:Npn \__fp_mul_significand_small_f:NNwwwN #1 #2#3; #4#5; #6; + #7 { - \c_one \exp_after:wN \__fp_basics_pack_high:NNNNNw @@ -2606,34 +2643,34 @@ \exp_after:wN #1 \int_use:N \__int_eval:w #3 - #6 - \exp_after:wN \__fp_div_mantissa_i_o:wnnw + \exp_after:wN \__fp_div_significand_i_o:wnnw \int_use:N \__int_eval:w #7 \use_i:nnnn #8 + \c_one ; #4 {#7}{#8}#9 ; #1 } -\cs_new:Npn \__fp_div_mantissa_i_o:wnnw #1 ; #2#3 #4 ; +\cs_new:Npn \__fp_div_significand_i_o:wnnw #1 ; #2#3 #4 ; { - \exp_after:wN \__fp_div_mantissa_test_o:w + \exp_after:wN \__fp_div_significand_test_o:w \int_use:N \__int_eval:w - \exp_after:wN \__fp_div_mantissa_calc:wwnnnnnnn + \exp_after:wN \__fp_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; #4 - { \exp_after:wN \__fp_div_mantissa_ii:wwn \__int_value:w #1 } - { \exp_after:wN \__fp_div_mantissa_ii:wwn \__int_value:w #1 } - { \exp_after:wN \__fp_div_mantissa_ii:wwn \__int_value:w #1 } - { \exp_after:wN \__fp_div_mantissa_iii:wwnnnnn \__int_value:w #1 } + { \exp_after:wN \__fp_div_significand_ii:wwn \__int_value:w #1 } + { \exp_after:wN \__fp_div_significand_ii:wwn \__int_value:w #1 } + { \exp_after:wN \__fp_div_significand_ii:wwn \__int_value:w #1 } + { \exp_after:wN \__fp_div_significand_iii:wwnnnnn \__int_value:w #1 } } -\cs_new:Npn \__fp_div_mantissa_calc:wwnnnnnnn 1#1 +\cs_new:Npn \__fp_div_significand_calc:wwnnnnnnn 1#1 { \if_meaning:w 1 #1 - \exp_after:wN \__fp_div_mantissa_calc_i:wwnnnnnnn + \exp_after:wN \__fp_div_significand_calc_i:wwnnnnnnn \else: - \exp_after:wN \__fp_div_mantissa_calc_ii:wwnnnnnnn + \exp_after:wN \__fp_div_significand_calc_ii:wwnnnnnnn \fi: } -\cs_new:Npn \__fp_div_mantissa_calc_i:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 +\cs_new:Npn \__fp_div_significand_calc_i:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 { 1 1 #1 #9 \exp_after:wN ; @@ -2650,7 +2687,7 @@ - #1 * #8 ; {#5}{#6}{#7}{#8} } -\cs_new:Npn \__fp_div_mantissa_calc_ii:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 +\cs_new:Npn \__fp_div_significand_calc_ii:wwnnnnnnn #1; #2;#3#4 #5#6#7#8 #9 { 1 0 #1 #9 \exp_after:wN ; @@ -2667,33 +2704,33 @@ - #1 * #8 ; {#5}{#6}{#7}{#8} } -\cs_new:Npn \__fp_div_mantissa_ii:wwn #1; #2;#3 +\cs_new:Npn \__fp_div_significand_ii:wwn #1; #2;#3 { - \exp_after:wN \__fp_div_mantissa_pack:NNN + \exp_after:wN \__fp_div_significand_pack:NNN \int_use:N \__int_eval:w - \exp_after:wN \__fp_div_mantissa_calc:wwnnnnnnn + \exp_after:wN \__fp_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ; } -\cs_new:Npn \__fp_div_mantissa_iii:wwnnnnn #1; #2;#3#4#5 #6#7 +\cs_new:Npn \__fp_div_significand_iii:wwnnnnn #1; #2;#3#4#5 #6#7 { 0 - \exp_after:wN \__fp_div_mantissa_iv:wwnnnnnnn + \exp_after:wN \__fp_div_significand_iv:wwnnnnnnn \int_use:N \__int_eval:w (\c_two * #2 #3) / #6 #7 ; % <- P #2 ; {#3} {#4} {#5} {#6} {#7} } -\cs_new:Npn \__fp_div_mantissa_iv:wwnnnnnnn #1; #2;#3#4#5 #6#7#8#9 +\cs_new:Npn \__fp_div_significand_iv:wwnnnnnnn #1; #2;#3#4#5 #6#7#8#9 { + \c_five * #1 - \exp_after:wN \__fp_div_mantissa_vi:Nw + \exp_after:wN \__fp_div_significand_vi:Nw \int_use:N \__int_eval:w -20 + 2*#2#3 - #1*#6#7 + - \exp_after:wN \__fp_div_mantissa_v:NN + \exp_after:wN \__fp_div_significand_v:NN \int_use:N \__int_eval:w 199980 + 2*#4 - #1*#8 + - \exp_after:wN \__fp_div_mantissa_v:NN + \exp_after:wN \__fp_div_significand_v:NN \int_use:N \__int_eval:w 200000 + 2*#5 - #1*#9 ; } -\cs_new:Npn \__fp_div_mantissa_v:NN #1#2 { #1#2 \__int_eval_end: + } -\cs_new:Npn \__fp_div_mantissa_vi:Nw #1#2; +\cs_new:Npn \__fp_div_significand_v:NN #1#2 { #1#2 \__int_eval_end: + } +\cs_new:Npn \__fp_div_significand_vi:Nw #1#2; { \if_meaning:w 0 #1 \if_int_compare:w \__int_eval:w #2 > \c_zero + \c_one \fi: @@ -2702,17 +2739,17 @@ \fi: ; } -\cs_new:Npn \__fp_div_mantissa_pack:NNN 1 #1 #2 { + #1 #2 ; } -\cs_new:Npn \__fp_div_mantissa_test_o:w 10 #1 +\cs_new:Npn \__fp_div_significand_pack:NNN 1 #1 #2 { + #1 #2 ; } +\cs_new:Npn \__fp_div_significand_test_o:w 10 #1 { \if_meaning:w 0 #1 - \exp_after:wN \__fp_div_mantissa_small_o:wwwNNNNwN + \exp_after:wN \__fp_div_significand_small_o:wwwNNNNwN \else: - \exp_after:wN \__fp_div_mantissa_large_o:wwwNNNNwN + \exp_after:wN \__fp_div_significand_large_o:wwwNNNNwN \fi: #1 } -\cs_new:Npn \__fp_div_mantissa_small_o:wwwNNNNwN +\cs_new:Npn \__fp_div_significand_small_o:wwwNNNNwN 0 #1; #2; #3; #4#5#6#7#8; #9 { \exp_after:wN \__fp_basics_pack_high:NNNNNw @@ -2722,7 +2759,7 @@ + \__fp_round:NNN #9 #7 #8 \exp_after:wN ; } -\cs_new:Npn \__fp_div_mantissa_large_o:wwwNNNNwN +\cs_new:Npn \__fp_div_significand_large_o:wwwNNNNwN #1; #2; #3; #4#5#6#7#8; #9 { + \c_one @@ -2736,13 +2773,13 @@ \__int_value:w \__fp_round_digit:Nw #7 #8 ; \exp_after:wN ; } -\cs_new:Npn \__fp_neg_o:w \s__fp \__fp_chk:w #1 #2 +\cs_new:Npn \__fp_neg_o:w #1 \s__fp \__fp_chk:w #2 #3 { \exp_after:wN \__fp_exp_after_o:w \exp_after:wN \s__fp \exp_after:wN \__fp_chk:w - \exp_after:wN #1 - \int_use:N \__int_eval:w \c_two - #2 \__int_eval_end: + \exp_after:wN #2 + \int_use:N \__int_eval:w \c_two - #3 \__int_eval_end: } \cs_new:Npn \__fp_abs_o:w \s__fp \__fp_chk:w #1 #2 { @@ -2788,6 +2825,12 @@ \tl_const:Nn \c__fp_one_fixed_tl { {10000} {0000} {0000} {0000} {0000} {0000} } \cs_new:Npn \__fp_fixed_continue:wn #1; #2 { #2 #1; } +\cs_new:Npn \__fp_fixed_add_one:wN #1#2; #3 + { + \exp_after:wN #3 \exp_after:wN + { \int_use:N \__int_eval:w \c_ten_thousand + #1 } #2 ; + } +\cs_new:Npn \__fp_fixed_mul_after:wn #1; #2 { #2 {#1} } \cs_new:Npn \__fp_fixed_div_int:wwN #1#2#3#4#5#6 ; #7 ; #8 { \exp_after:wN \__fp_fixed_div_int_after:Nw @@ -2799,7 +2842,7 @@ #3; {#7} \__fp_fixed_div_int_ii:wnn #4; {#7} \__fp_fixed_div_int_ii:wnn #5; {#7} \__fp_fixed_div_int_ii:wnn - #6; {#7} \__fp_fixed_div_int_end:wnn ; + #6; {#7} \__fp_fixed_div_int_iii:wnn ; } \cs_new:Npn \__fp_fixed_div_int_i:wnN #1; #2 #3 { @@ -2816,110 +2859,104 @@ \exp_after:wN \__fp_fixed_div_int_i:wnN \int_use:N \__int_eval:w #3 - #1*#2 \__int_eval_end: } -\cs_new:Npn \__fp_fixed_div_int_end:wnn #1; #2 #3 { + #1 + \c_two ; } +\cs_new:Npn \__fp_fixed_div_int_iii:wnn #1; #2 #3 { + #1 + \c_two ; } \cs_new:Npn \__fp_fixed_div_int_pack:Nw #1 #2; { + #1; {#2} } \cs_new:Npn \__fp_fixed_div_int_after:Nw #1 #2; { #1 {#2} } -\cs_new:Npn \__fp_fixed_add_one:wN #1#2; #3 - { - \exp_after:wN #3 \exp_after:wN - { \int_use:N \__int_eval:w 10000 + #1 } #2 ; - } -\cs_new_nopar:Npn \__fp_fixed_add:wwN { \__fp_fixed_add_i:NNnnnnwnn + + } -\cs_new_nopar:Npn \__fp_fixed_sub:wwN { \__fp_fixed_add_i:NNnnnnwnn + - } -\cs_new_nopar:Npn \__fp_fixed_sub_back:wwN { \__fp_fixed_add_i:NNnnnnwnn - + } -\cs_new:Npn \__fp_fixed_add_i:NNnnnnwnn #1#2 #3#4#5#6 #7; #8#9 - { - \exp_after:wN \__fp_fixed_add_after:NNNNNwN - \int_use:N \__int_eval:w 1 9999 9998 #1 #3#4 #2 #8#9 - \exp_after:wN \__fp_fixed_add_pack:NNNNNwN - \int_use:N \__int_eval:w 1 9999 9998 #1 #5#6 - \__fp_fixed_add_ii:NnnNnnnnw #1 #7 #2 - } -\cs_new:Npn \__fp_fixed_add_ii:NnnNnnnnw #1 #2#3 #4 #5#6 #7#8 ; #9 - { - #4 #5#6 - \exp_after:wN \__fp_fixed_add_pack:NNNNNwN - \int_use:N \__int_eval:w 2 0000 0000 #4 #7#8 #1 #2#3 ; #9 ; - } -\cs_new:Npn \__fp_fixed_add_pack:NNNNNwN #1 #2#3#4#5 #6; #7 - { + #1 ; #7 {#2#3#4#5} {#6} } -\cs_new:Npn \__fp_fixed_add_after:NNNNNwN #1 #2#3#4#5 #6; #7 - { - \exp_after:wN #7 - \exp_after:wN { \int_use:N \__int_eval:w - 2 0000 + #1#2#3#4#5 } - {#6} - } +\cs_new_nopar:Npn \__fp_fixed_add:wwn { \__fp_fixed_add_i:Nnnnnwnn + } +\cs_new_nopar:Npn \__fp_fixed_sub:wwn { \__fp_fixed_add_i:Nnnnnwnn - } +\cs_new:Npn \__fp_fixed_add_i:Nnnnnwnn #1 #2#3#4#5 #6; #7#8 + { + \exp_after:wN \__fp_fixed_add_after:NNNNNwn + \int_use:N \__int_eval:w 9 9999 9998 + #2#3 #1 #7#8 + \exp_after:wN \__fp_fixed_add_pack:NNNNNwn + \int_use:N \__int_eval:w 1 9999 9998 + #4#5 + \__fp_fixed_add_ii:nnNnnnwn #6 #1 + } +\cs_new:Npn \__fp_fixed_add_ii:nnNnnnwn #1#2 #3 #4#5 #6#7 ; #8 + { + #3 #4#5 + \exp_after:wN \__fp_fixed_add_pack:NNNNNwn + \int_use:N \__int_eval:w 2 0000 0000 #3 #6#7 + #1#2 ; {#8} ; + } +\cs_new:Npn \__fp_fixed_add_pack:NNNNNwn #1 #2#3#4#5 #6; #7 + { + #1 ; {#7} {#2#3#4#5} {#6} } +\cs_new:Npn \__fp_fixed_add_after:NNNNNwn 1 #1 #2#3#4#5 #6; #7 + { #7 {#1#2#3#4#5} {#6} } \cs_new:Npn \__fp_fixed_mul:wwn #1#2#3#4 #5; #6#7#8#9 { - \exp_after:wN \__fp_fixed_mul_after:wwn + \exp_after:wN \__fp_fixed_mul_after:wn \int_use:N \__int_eval:w \c__fp_leading_shift_int - \exp_after:wN \__fp_pack:NNNNNw + \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#6 - \exp_after:wN \__fp_pack:NNNNNw + \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#7 + #2*#6 - \exp_after:wN \__fp_pack:NNNNNw + \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#8 + #2*#7 + #3*#6 - \exp_after:wN \__fp_pack:NNNNNw + \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1*#9 + #2*#8 + #3*#7 + #4*#6 - \exp_after:wN \__fp_pack:NNNNNw + \exp_after:wN \__fp_pack:NNNNNwn \int_use:N \__int_eval:w \c__fp_trailing_shift_int + #2*#9 + #3*#8 + #4*#7 + ( #3*#9 + #4*#8 - + \__fp_fixed_mul_i:nnnnnnnn #5 {#6}{#7} {#1}{#2} - } -\cs_new:Npn \__fp_fixed_mul_i:nnnnnnnn #1#2 #3#4 #5#6 #7#8 - { #1*#4 + #2*#3 + #5*#8 + #6*#7 )/10000 + #1*#3 + #5*#7 ; } -\cs_new:Npn \__fp_fixed_mul_pack:NNNNNw - #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} } -\cs_new:Npn \__fp_fixed_mul_after:wwn #1; #2; #3 { #3 {#1} #2 ; } -\cs_new:Npn \__fp_fixed_one_minus_mul:wwn #1; #2#3#4#5; - { - \exp_after:wN \__fp_fixed_mul_after:wwn - \int_use:N \__int_eval:w \c__fp_big_leading_shift_int + \c_ten_thousand - \exp_after:wN \__fp_pack_big:NNNNNNw + + \__fp_fixed_mul_i:nnnnnnnwn #5 {#6}{#7} {#1}{#2} + } +\cs_new:Npn \__fp_fixed_mul_i:nnnnnnnwn #1#2 #3#4 #5#6 #7#8 ; #9 + { + #1*#4 + #2*#3 + #5*#8 + #6*#7 ) / \c_ten_thousand + + #1*#3 + #5*#7 ; + {#9} ; + } +\cs_new:Npn \__fp_fixed_mul_add:wwwn #1; #2; #3#4#5#6#7#8; #9 + { + \exp_after:wN \__fp_fixed_mul_after:wn + \int_use:N \__int_eval:w \c__fp_big_leading_shift_int + \exp_after:wN \__fp_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #3 #4 + \__fp_fixed_mul_add_i:Nwnnnwnnn + + + #5 #6 ; #2 ; #1 ; #2 ; + + + #7 #8 ; {#9} ; + } +\cs_new:Npn \__fp_fixed_mul_sub_back:wwwn #1; #2; #3#4#5#6#7#8; #9 + { + \exp_after:wN \__fp_fixed_mul_after:wn + \int_use:N \__int_eval:w \c__fp_big_leading_shift_int + \exp_after:wN \__fp_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #3 #4 + \__fp_fixed_mul_add_i:Nwnnnwnnn - + + #5 #6 ; #2 ; #1 ; #2 ; - + + #7 #8 ; {#9} ; + } +\cs_new:Npn \__fp_fixed_one_minus_mul:wwn #1; #2; #3 + { + \exp_after:wN \__fp_fixed_mul_after:wn + \int_use:N \__int_eval:w \c__fp_big_leading_shift_int + \exp_after:wN \__fp_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + 1 0000 0000 + \__fp_fixed_mul_add_i:Nwnnnwnnn - + ; #2 ; #1 ; #2 ; - + ; {#3} ; + } +\cs_new:Npn \__fp_fixed_mul_add_i:Nwnnnwnnn #1 #2; #3#4#5#6; #7#8#9 + { + #1 #7*#3 + \exp_after:wN \__fp_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #1 #7*#4 #1 #8*#3 + \exp_after:wN \__fp_pack_big:NNNNNNwn \int_use:N \__int_eval:w \c__fp_big_middle_shift_int - \__fp_fixed_mul_add_i:Nnwnnwnnn - - 00; {#2}{#3}{#4}; #1; {#2}{#3}{#4}#5; - 00 ; - } -\cs_new:Npn \__fp_fixed_mul_add:wwwn #1; #2#3#4#5; #6#7#8#9 - { - \exp_after:wN \__fp_fixed_mul_after:wwn - \int_use:N \__int_eval:w \c__fp_big_leading_shift_int + #6 - \exp_after:wN \__fp_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #7 - \__fp_fixed_mul_add_i:Nnwnnwnnn - + {#8}{#9}; {#2}{#3}{#4}; #1; {#2}{#3}{#4}#5; + - } -\cs_new:Npn \__fp_fixed_mul_sub_back:wwwn #1; #2#3#4#5; #6#7#8#9 - { - \exp_after:wN \__fp_fixed_mul_after:wwn - \int_use:N \__int_eval:w \c__fp_big_leading_shift_int + #6 - \exp_after:wN \__fp_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #7 - \__fp_fixed_mul_add_i:Nnwnnwnnn - - {#8}{#9}; {#2}{#3}{#4}; #1; {#2}{#3}{#4}#5; - - } -\cs_new:Npn \__fp_fixed_mul_add_i:Nnwnnwnnn #1 #2#3; #4#5#6; #7#8#9 - { % sg z3z4; y1y2y3; x1x2x3 x4x5x6; y1y2y3y4y5y6; sg z5z6; - #1 #7*#4 - \exp_after:wN \__fp_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #2 - #1 #7*#5 #1 #8*#4 - \exp_after:wN \__fp_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #3 - #1 #7*#6 #1 #8*#5 #1 #9*#4 - \exp_after:wN \__fp_pack_big:NNNNNNw - \int_use:N \__int_eval:w \c__fp_big_middle_shift_int - #1 \__fp_fixed_mul_add_ii:nnnnwnnnn {#7}{#8}{#9} + #1 #7*#5 #1 #8*#4 #1 #9*#3 #2 + \exp_after:wN \__fp_pack_big:NNNNNNwn + \int_use:N \__int_eval:w \c__fp_big_middle_shift_int + #1 \__fp_fixed_mul_add_ii:nnnnwnnnn {#7}{#8}{#9} } \cs_new:Npn \__fp_fixed_mul_add_ii:nnnnwnnnn #1#2#3#4#5; #6#7#8#9 - { % x1x2x3x4 x5x6; y1y2y3y4 y5y6; sg z5z6; + { ( #1*#9 + #2*#8 + #3*#7 + #4*#6 ) - \exp_after:wN \__fp_pack_big:NNNNNNw + \exp_after:wN \__fp_pack_big:NNNNNNwn \int_use:N \__int_eval:w \c__fp_big_trailing_shift_int \__fp_fixed_mul_add_iii:nnnnwnnwN { #6 + #4*#7 + #3*#8 + #2*#9 + #1 } @@ -2928,15 +2965,9 @@ {#6} } \cs_new:Npn \__fp_fixed_mul_add_iii:nnnnwnnwN #1#2 #3#4#5; #6#7#8; #9 - { % {y1+x4*y2+x3*y3+x2*y4+x1} {y2+x4*y3+x3*y4+x2} - % x1x5x6; y1y5y6; sg z5z6; - % => - % sg (x5*y1+x4*y2+x3*y3+x2*y4+x1*y5) - % sg (x6*y1+x5*y2+x4*y3+x3*y4+x2*y5+x1*y6)/10000 - % + z5z6; + { #9 (#4* #1 *#7) #9 (#5*#6+#4* #2 *#7+#3*#8) / \c_ten_thousand - + \__fp_use_s:nn } \cs_new:Npn \__fp_fixed_to_float:Nw #1#2; { \__fp_fixed_to_float:wN #2; #1 } \cs_new:Npn \__fp_fixed_to_float:wN #1#2#3#4#5#6; #7 @@ -2996,7 +3027,7 @@ } \cs_new:Npn \__fp_fixed_inv_to_float:wN #1#2; #3 { - - \__int_eval:w + + \__int_eval:w % ^^A todo: remove the +? \if_int_compare:w #1 < \c_one_thousand \__fp_fixed_dtf_zeros:wNnnnnnn \fi: @@ -3092,7 +3123,7 @@ { #1 ; {#2#3#4#5} {#6} } \cs_new:Npn \__fp_fixed_dtf_epsilon_ii:NNNNNww #1#2#3#4#5#6; #7; { - \__fp_fixed_mul:wwn %^^A todo: optimize to use \__fp_mul_mantissa. + \__fp_fixed_mul:wwn %^^A todo: optimize to use \__fp_mul_significand. {0000} {#2#3#4#5} {#6} #7 ; {0000} {#2#3#4#5} {#6} #7 ; \__fp_fixed_add_one:wN @@ -3209,7 +3240,7 @@ } \cs_new:Npn \__fp_ln_x_iv:wnnnnnnnn #1; #2#3#4#5 #6#7#8#9 { - \exp_after:wN \__fp_div_mantissa_pack:NNN + \exp_after:wN \__fp_div_significand_pack:NNN \int_use:N \__int_eval:w \__fp_ln_div_i:w #1 ; #6 #7 ; {#8} {#9} @@ -3222,20 +3253,20 @@ } \cs_new:Npn \__fp_ln_div_i:w #1; { - \exp_after:wN \__fp_div_mantissa_calc:wwnnnnnnn + \exp_after:wN \__fp_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + 2 0000 0000 / #1 ; % Q1 } \cs_new:Npn \__fp_ln_div_ii:wwn #1; #2;#3 % y; B1;B2 <- for k=1 { - \exp_after:wN \__fp_div_mantissa_pack:NNN + \exp_after:wN \__fp_div_significand_pack:NNN \int_use:N \__int_eval:w - \exp_after:wN \__fp_div_mantissa_calc:wwnnnnnnn + \exp_after:wN \__fp_div_significand_calc:wwnnnnnnn \int_use:N \__int_eval:w 999999 + #2 #3 / #1 ; % Q2 #2 #3 ; } \cs_new:Npn \__fp_ln_div_vi:wwn #1; #2;#3#4#5 #6#7#8#9 %y;F1;F2F3F4x1x2x3x4 { - \exp_after:wN \__fp_div_mantissa_pack:NNN + \exp_after:wN \__fp_div_significand_pack:NNN \int_use:N \__int_eval:w 1000000 + #2 #3 / #1 ; % Q6 } \cs_new:Npn \__fp_ln_div_after:Nw #1#2; @@ -3303,7 +3334,7 @@ \__fp_ln_Taylor_break:w \fi: \exp_after:wN \__fp_fixed_div_int:wwN \c__fp_one_fixed_tl ; #1; - \__fp_fixed_add:wwN #2; + \__fp_fixed_add:wwn #2; \__fp_fixed_mul:wwn #3; { \exp_after:wN \__fp_ln_Taylor_loop:www @@ -3311,7 +3342,7 @@ } #3; } -\cs_new:Npn \__fp_ln_Taylor_break:w \fi: #1 \__fp_fixed_add:wwN #2#3; #4 ;; +\cs_new:Npn \__fp_ln_Taylor_break:w \fi: #1 \__fp_fixed_add:wwn #2#3; #4 ;; { \fi: \exp_after:wN \__fp_fixed_mul:wwn @@ -3320,9 +3351,9 @@ \cs_new:Npn \__fp_ln_c:NwNw #1 #2; #3 { \if_meaning:w + #1 - \exp_after:wN \exp_after:wN \exp_after:wN \__fp_fixed_sub:wwN + \exp_after:wN \exp_after:wN \exp_after:wN \__fp_fixed_sub:wwn \else: - \exp_after:wN \exp_after:wN \exp_after:wN \__fp_fixed_add:wwN + \exp_after:wN \exp_after:wN \exp_after:wN \__fp_fixed_add:wwn \fi: #3 ; #2 ; } @@ -3336,11 +3367,11 @@ \if_int_compare:w #2 > \c_zero \exp_after:wN \__fp_ln_exponent_small:NNww \exp_after:wN 0 - \exp_after:wN \__fp_fixed_sub:wwN \__int_value:w + \exp_after:wN \__fp_fixed_sub:wwn \__int_value:w \else: \exp_after:wN \__fp_ln_exponent_small:NNww \exp_after:wN 2 - \exp_after:wN \__fp_fixed_add:wwN \__int_value:w - + \exp_after:wN \__fp_fixed_add:wwn \__int_value:w - \fi: \fi: #2; #1; @@ -3348,7 +3379,7 @@ \cs_new:Npn \__fp_ln_exponent_one:ww 1; #1; { \c_zero - \exp_after:wN \__fp_fixed_sub:wwN \c__fp_ln_x_fixed_tl ; #1; + \exp_after:wN \__fp_fixed_sub:wwn \c__fp_ln_x_fixed_tl ; #1; \__fp_fixed_to_float:wN 0 } \cs_new:Npn \__fp_ln_exponent_small:NNww #1#2#3; #4#5#6#7#8#9; @@ -3421,7 +3452,7 @@ } #5 {#4} - #2 0 + #1 #2 0 \tex_romannumeral:D \fi: \fi: @@ -3429,8 +3460,9 @@ } \cs_new:Npn \__fp_exp_overflow: { + \c_two * \c__fp_max_exponent_int ; {1000} {0000} {0000} {0000} ; } -\cs_new:Npn \__fp_exp_Taylor:Nnnwn #1#2#3 #4; #5 +\cs_new:Npn \__fp_exp_Taylor:Nnnwn #1#2#3 #4; #5 #6 { + #6 \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN \__fp_pack_twice_four:wNNNNNNNN @@ -3562,9 +3594,9 @@ #1; \__fp_exp_large_after:wwn } -\cs_new:Npn \__fp_exp_large_after:wwn #1; #2; +\cs_new:Npn \__fp_exp_large_after:wwn #1; #2; #3 { - \__fp_exp_Taylor:Nnnwn ? { } { } 0 #2; {} + \__fp_exp_Taylor:Nnnwn ? { } { } 0 #2; {} #3 \__fp_fixed_mul:wwn #1; } \cs_new:cpn { __fp_ \iow_char:N \^ _o:ww } @@ -3599,6 +3631,13 @@ \fi: \if_meaning:w #1 #4 \__fp_case_return_o:Nw \c_zero_fp + \fi: + \if_meaning:w 0 #1 + \__fp_case_use:nw + { + \__fp_division_by_zero_o:NNww \c_inf_fp ^ + \s__fp \__fp_chk:w #1 #2 ; + } \else: \__fp_case_return_o:Nw \c_inf_fp \fi: @@ -3613,7 +3652,7 @@ \fi: \__fp_case_return_o:Nww \c_one_fp \fi: - \if_case:w #4 ~ + \if_case:w #4 \exp_stop_f: \or: \exp_after:wN \__fp_pow_npos:Nww \exp_after:wN #5 @@ -3638,50 +3677,57 @@ \exp_after:wN 0 \__int_value:w \if:w #1 \if_int_compare:w #3 > \c_zero 0 \else: 2 \fi: - \exp_after:wN \__fp_pow_npos_aux:Nnww + \exp_after:wN \__fp_pow_npos_aux:NNnww + \exp_after:wN + \exp_after:wN \__fp_fixed_to_float:wN \else: - - - \exp_after:wN \__fp_pow_npos_aux:Nnww + \exp_after:wN \__fp_pow_npos_aux:NNnww + \exp_after:wN - \exp_after:wN \__fp_fixed_inv_to_float:wN \fi: {#3} } -\cs_new:Npn \__fp_pow_npos_aux:Nnww #1#2#3#4; \s__fp \__fp_chk:w 1#5#6#7; +\cs_new:Npn \__fp_pow_npos_aux:NNnww #1#2#3#4#5; \s__fp \__fp_chk:w 1#6#7#8; { + #1 \__int_eval:w - \__fp_ln_significand:NNNNnnnN #3#4 - \__fp_pow_exponent:wnN {#2} - \__fp_fixed_mul:wwn #7 {0000}{0000} ; - \__fp_pow_B:wwN #6; - #1 0 % fixed_to_float:wN + \__fp_ln_significand:NNNNnnnN #4#5 + \__fp_pow_exponent:wnN {#3} + \__fp_fixed_mul:wwn #8 {0000}{0000} ; + \__fp_pow_B:wwN #7; + #1 #2 0 % fixed_to_float:wN } \cs_new:Npn \__fp_pow_exponent:wnN #1; #2 { \if_int_compare:w #2 > \c_zero - \exp_after:wN \__fp_pow_exponent:Nwnnnnnn % n\ln(10) - (-\ln(x)) + \exp_after:wN \__fp_pow_exponent:Nwnnnnnwn % n\ln(10) - (-\ln(x)) \exp_after:wN + \else: - \exp_after:wN \__fp_pow_exponent:Nwnnnnnn % -( |n|\ln(10) + (-\ln(x)) ) + \exp_after:wN \__fp_pow_exponent:Nwnnnnnwn % -( |n|\ln(10) + (-\ln(x)) ) \exp_after:wN - \fi: #2; #1; } -\cs_new:Npn \__fp_pow_exponent:Nwnnnnnn #1#2; #3#4#5#6#7#8; - { %^^A todo: use that in ln. %^^A todo: log(1.00...) too inaccurate? - \exp_after:wN \__fp_fixed_mul_after:wwn - \int_use:N \__int_eval:w -5 0000 - \exp_after:wN \__fp_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 #1#2*23025 - #1 #3 - \exp_after:wN \__fp_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 #1 #2*8509 - #1 #4 - \exp_after:wN \__fp_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 #1 #2*2994 - #1 #5 - \exp_after:wN \__fp_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 #1 #2*0456 - #1 #6 - \exp_after:wN \__fp_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 5 0000 0000 #1 #2*8401 - #1 #7 - #1 ( #2*7991 - #8 ) / 1 0000 ; ; +\cs_new:Npn \__fp_pow_exponent:Nwnnnnnwn #1#2; #3#4#5#6#7#8; #9 + { %^^A todo: use that in ln. + \exp_after:wN \__fp_fixed_mul_after:wn + \int_use:N \__int_eval:w \c__fp_leading_shift_int + \exp_after:wN \__fp_pack:NNNNNwn + \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1#2*23025 - #1 #3 + \exp_after:wN \__fp_pack:NNNNNwn + \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1 #2*8509 - #1 #4 + \exp_after:wN \__fp_pack:NNNNNwn + \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1 #2*2994 - #1 #5 + \exp_after:wN \__fp_pack:NNNNNwn + \int_use:N \__int_eval:w \c__fp_middle_shift_int + #1 #2*0456 - #1 #6 + \exp_after:wN \__fp_pack:NNNNNwn + \int_use:N \__int_eval:w \c__fp_trailing_shift_int + #1 #2*8401 - #1 #7 + #1 ( #2*7991 - #8 ) / 1 0000 ; {#9} ; } \cs_new:Npn \__fp_pow_B:wwN #1#2#3#4#5#6; #7; { @@ -3698,7 +3744,7 @@ \int_use:N \__int_eval:w 10 0000 + #1 \__int_eval_end: #2#3#4#5#6 0000 0000 0000 0000 0000 0000 ; %^^A todo: how many 0? } -\cs_new:Npn \__fp_pow_C_overflow:w #1; #2; +\cs_new:Npn \__fp_pow_C_overflow:w #1; #2; #3 { + \c_two * \c__fp_max_exponent_int \exp_after:wN \__fp_fixed_continue:wn \c__fp_one_fixed_tl ; @@ -3729,7 +3775,7 @@ \cs_new:Npn \__fp_pow_neg:www \s__fp \__fp_chk:w #1#2; #3; #4; { \if_case:w \__fp_pow_neg_case:w #4 ; - \exp_after:wN \__fp_pow_neg_neg:w + \exp_after:wN \__fp_neg_o:w \or: \if_int_compare:w \__int_eval:w #1 / \c_two = \c_one \__fp_invalid_operation_o:Nww ^ #3; #4; @@ -3741,14 +3787,6 @@ \__fp_exp_after_o:w \s__fp \__fp_chk:w #1#2; } -\cs_new:Npn \__fp_pow_neg_neg:w \__fp_exp_after_o:w \s__fp \__fp_chk:w #1#2 - { - \exp_after:wN \__fp_exp_after_o:w - \exp_after:wN \s__fp - \exp_after:wN \__fp_chk:w - \exp_after:wN #1 - \int_use:N \__int_eval:w \c_two - #2 \__int_eval_end: - } \cs_new:Npn \__fp_pow_neg_case:w \s__fp \__fp_chk:w #1#2#3; { \if_case:w #1 \exp_stop_f: @@ -3826,24 +3864,17 @@ %% %% ----------------------------------------------------------------------- %% -\cs_new_nopar:Npx \__fp_one_over:w - { - \exp_not:N \exp_after:wN - \exp_not:c { __fp_/_o:ww } - \exp_not:N \c_one_fp - } \cs_new:Npn \__fp_sin_o:w \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: \__fp_case_return_same_o:w \or: - \exp_after:wN \__fp_trig_exponent:NNNNwn - \exp_after:wN \__fp_sin_series:NNwww - \exp_after:wN ? - \exp_after:wN #2 - \exp_after:wN \c_zero - \or: - \__fp_case_use:nw { \__fp_invalid_operation_o:nw { sin } } + \__fp_case_use:nw + { + \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_o:w + \__fp_sin_series:NNwww \__fp_fixed_to_float:wN #2 \c_zero + } + \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { sin } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 @@ -3853,16 +3884,42 @@ \if_case:w #1 \exp_stop_f: \__fp_case_return_o:Nw \c_one_fp \or: - \__fp_case_use:nw %^^A todo: is that faster than the exp_after route? + \__fp_case_use:nw { - \__fp_trig_exponent:NNNNwn - \__fp_sin_series:NNwww - ? - 0 - \c_two + \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_one_o:w + \__fp_sin_series:NNwww \__fp_fixed_to_float:wN 0 \c_two } + \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { cos } } + \else: \__fp_case_return_same_o:w + \fi: + \s__fp \__fp_chk:w #1#2 + } +\cs_new:Npn \__fp_csc_o:w \s__fp \__fp_chk:w #1#2 + { + \if_case:w #1 \exp_stop_f: + \__fp_cot_zero_o:Nnw #2 { csc } + \or: + \__fp_case_use:nw + { + \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_inv_o:w + \__fp_sin_series:NNwww \__fp_fixed_inv_to_float:wN #2 \c_zero + } + \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { csc } } + \else: \__fp_case_return_same_o:w + \fi: + \s__fp \__fp_chk:w #1#2 + } +\cs_new:Npn \__fp_sec_o:w \s__fp \__fp_chk:w #1#2 + { + \if_case:w #1 \exp_stop_f: + \__fp_case_return_o:Nw \c_one_fp \or: - \__fp_case_use:nw { \__fp_invalid_operation_o:nw { cos } } + \__fp_case_use:nw + { + \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_one_o:w + \__fp_sin_series:NNwww \__fp_fixed_inv_to_float:wN 0 \c_two + } + \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { sec } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 @@ -3872,13 +3929,12 @@ \if_case:w #1 \exp_stop_f: \__fp_case_return_same_o:w \or: - \exp_after:wN \__fp_trig_exponent:NNNNwn - \exp_after:wN \__fp_tan_series:NNwww - \exp_after:wN 0 - \exp_after:wN #2 - \exp_after:wN \c_one - \or: - \__fp_case_use:nw { \__fp_invalid_operation_o:nw { tan } } + \__fp_case_use:nw + { + \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_o:w + \__fp_tan_series_o:NNwww 0 #2 \c_one + } + \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { tan } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 @@ -3886,129 +3942,126 @@ \cs_new:Npn \__fp_cot_o:w \s__fp \__fp_chk:w #1#2 { \if_case:w #1 \exp_stop_f: - \exp_after:wN \__fp_one_over:w - \or: - \exp_after:wN \__fp_trig_exponent:NNNNwn - \exp_after:wN \__fp_tan_series:NNwww - \exp_after:wN 2 - \exp_after:wN #2 - \exp_after:wN \c_three + \__fp_cot_zero_o:Nnw #2 { cot } \or: - \__fp_case_use:nw { \__fp_invalid_operation_o:nw { cot } } + \__fp_case_use:nw + { + \__fp_trig_exponent:NNNNNwn \__fp_trig_epsilon_inv_o:w + \__fp_tan_series_o:NNwww 2 #2 \c_three + } + \or: \__fp_case_use:nw { \__fp_invalid_operation_o:nw { cot } } \else: \__fp_case_return_same_o:w \fi: \s__fp \__fp_chk:w #1#2 } -\cs_new:Npn \__fp_trig_exponent:NNNNwn #1#2#3#4 \s__fp \__fp_chk:w 1#5#6 +\cs_new:Npn \__fp_cot_zero_o:Nnw #1 #2 #3 \fi: { - \if_int_compare:w #6 > - \c_eight - \exp_after:wN #1 + \fi: + \if_meaning:w 0 #1 + \exp_after:wN \__fp_division_by_zero_o:Nnw \exp_after:wN \c_inf_fp + \else: + \exp_after:wN \__fp_division_by_zero_o:Nnw \exp_after:wN \c_minus_inf_fp + \fi: + {#2} + } +\cs_new:Npn \__fp_trig_exponent:NNNNNwn #1#2#3#4#5 \s__fp \__fp_chk:w 1#6#7 + { + \if_int_compare:w #7 > - \c_eight \exp_after:wN #2 \exp_after:wN #3 - \int_use:N \__int_eval:w #4 - \if_int_compare:w #6 > \c_zero - \exp_after:wN \__fp_trig_large:w \__int_value:w + \exp_after:wN #4 + \int_use:N \__int_eval:w #5 + \if_int_compare:w #7 > \c_zero + \exp_after:wN \__fp_trig_large:ww \__int_value:w \else: - \exp_after:wN \__fp_trig_small:w \__int_value:w + \exp_after:wN \__fp_trig_small:ww \__int_value:w \fi: \else: - \if_case:w #4 - \__fp_sin_epsilon:w - \or: \__fp_sin_epsilon:w - \or: \__fp_cos_epsilon:w - \else: \__fp_cot_epsilon:w - \fi: - #5 + \exp_after:wN #1 + \exp_after:wN #6 \fi: - #6 ; - } -\cs_new:Npn \__fp_sin_epsilon:w #1 \fi: #2 \fi: #3 ; - { \fi: \fi: \__fp_exp_after_o:w \s__fp \__fp_chk:w 1 #2 {#3} } -\cs_new:Npn \__fp_cos_epsilon:w #1 \fi: #2 \fi: #3 ; #4 ; - { \fi: \fi: \exp_after:wN \c_one_fp } -\cs_new:Npn \__fp_cot_epsilon:w \fi: #1 \fi: #2 ; - { \fi: \fi: \__fp_one_over:w \s__fp \__fp_chk:w 1 #1 {#2} } -\cs_new:Npn \__fp_trig_small:w #1; - { - \exp_after:wN \exp_after:wN \exp_after:wN \__fp_trig_small_aux:wwNN - \prg_replicate:nn { - #1 } { 0 } ; + #7 ; } -\cs_new:Npn \__fp_trig_small_aux:wwNN #1; #2#3#4#5; +\cs_new:Npn \__fp_trig_epsilon_o:w #1 #2 ; + { \__fp_exp_after_o:w \s__fp \__fp_chk:w 1 #1 {#2} } +\cs_new:Npn \__fp_trig_epsilon_one_o:w #1 ; #2 ; + { \exp_after:wN \c_one_fp } +\group_begin: + \char_set_catcode_letter:N / + \cs_new:Npn \__fp_trig_epsilon_inv_o:w #1 #2 ; + { + \exp_after:wN \__fp_/_o:ww + \c_one_fp + \s__fp \__fp_chk:w 1 #1 {#2} + } +\group_end: +\cs_new:Npn \__fp_trig_small:ww #1; #2#3#4#5; { - \__fp_pack_twice_four:wNNNNNNNN - \__fp_pack_twice_four:wNNNNNNNN - \__fp_pack_twice_four:wNNNNNNNN - . - ; - #1#2#3#4#5 0000 0000; + \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN + \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN + \exp_after:wN \__fp_pack_twice_four:wNNNNNNNN + \exp_after:wN . + \exp_after:wN ; + \tex_romannumeral:D -`0 + \prg_replicate:nn { - #1 } { 0 } #2#3#4#5 0000 0000 ; } -\cs_new:Npn \__fp_trig_large:w #1; #2#3; +\cs_new:Npn \__fp_trig_large:ww #1; #2#3; { \__fp_trig_large_i:www #2; #3 ; #1; } \cs_new:Npn \__fp_trig_large_i:www #1; #2; #3; { \if_meaning:w 0 #3 \__fp_trig_large_break:w \fi: - \exp_after:wN \__fp_trig_large_ii:wnnnnnn + \exp_after:wN \__fp_trig_large_ii_o:wnnnn \int_use:N \__int_eval:w ( #1 - 3141 ) / 6283 ; - {#1} #2; + {#1} #2 + \exp_after:wN ; \int_use:N \__int_eval:w \c_minus_one + #3; } -\cs_new:Npn \__fp_trig_large_ii:wnnnnnn #1; #2#3#4#5; +\cs_new:Npn \__fp_trig_large_ii_o:wnnnn #1; #2#3#4#5 { \exp_after:wN \__fp_trig_large_i:www - \int_use:N \__int_eval:w -5 0000 + #20 - #1*62831 - \exp_after:wN \__fp_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 + #30 - #1*8530 - \exp_after:wN \__fp_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 4 9995 0000 + #40 - #1*7179 - \exp_after:wN \__fp_fixed_mul_pack:NNNNNw - \int_use:N \__int_eval:w 5 0000 0000 + #50 - #1*5880 - \exp_after:wN ; + \int_use:N \__int_eval:w \c__fp_leading_shift_int + #20 - #1*62831 + \exp_after:wN \__fp_pack:NNNNNw + \int_use:N \__int_eval:w \c__fp_middle_shift_int + #30 - #1*8530 + \exp_after:wN \__fp_pack:NNNNNw + \int_use:N \__int_eval:w \c__fp_middle_shift_int + #40 - #1*7179 + \exp_after:wN \__fp_pack:NNNNNw + \int_use:N \__int_eval:w \c__fp_trailing_shift_int + #50 - #1*5880 \exp_after:wN ; } \cs_new:Npn \__fp_trig_large_break:w \fi: #1; #2; - { \fi: \__fp_trig_octant_loop:nw #2 {0000} {0000} ; } -\cs_new:Npn \__fp_trig_octant_loop:nw #1#2; + { \fi: \__fp_trig_octant_loop:nnnnnw #2 {0000} {0000} ; } +\cs_new:Npn \__fp_trig_octant_loop:nnnnnw #1#2#3#4#5#6; { - \if_int_compare:w #1 < 15707 \exp_stop_f: + \if_int_compare:w #1#2 < 157079633 \exp_stop_f: + \if_int_compare:w #1#2 = 157079632 \exp_stop_f: + \if_int_compare:w #3#4 > 67948969 \exp_stop_f: + \use_i_ii:nnn + \fi: + \fi: \__fp_trig_octant_break:w \fi: + \c_two - \__fp_fixed_sub_back:wwN + \__fp_fixed_sub:wwn + {#1} {#2} {#3} {#4} {0000} {0000} ; {15707} {9632} {6794} {8970} {0000} {0000} ; - {#1} #2; - \__fp_trig_octant_loop:nw + \__fp_trig_octant_loop:nnnnnw } -\cs_new:Npn \__fp_trig_octant_break:w #1 \fi: + #2#3 #4; #5#6; #7; +\cs_new:Npn \__fp_trig_octant_break:w #1 \fi: + #2#3 #4#5; #6; #7; { \fi: - \if_int_compare:w #5 < 7854 \exp_stop_f: - \if_int_compare:w #5 < \c_zero - \exp_after:wN \__fp_trig_octant_neg:w - \fi: + \if_int_compare:w #4 < 7854 \exp_stop_f: \exp_after:wN \__fp_use_i_until_s:nw \exp_after:wN . \fi: + \c_one - \__fp_fixed_sub:wwN - {15707} {9632} {6794} {8970} {0000} {0000} ; - {#5} #6 ; . ; - } -\cs_new:Npn \__fp_trig_octant_neg:w #1\fi: #2; #3#4#5#6#7#8; #9 - { - \fi: - + \c_seven - \exp_after:wN \__fp_fixed_add_after:NNNNNwN - \int_use:N \__int_eval:w 1 9999 9998 - #30000 - #4 - \exp_after:wN \__fp_fixed_add_pack:NNNNNwN - \int_use:N \__int_eval:w 1 9999 9998 - #5#6 - \exp_after:wN \__fp_fixed_add_pack:NNNNNwN - \int_use:N \__int_eval:w 2 0000 0000 - #7#8 ; {#9} ; + \__fp_fixed_sub:wwn #6 ; {#4} #5 ; . ; } \cs_new:Npn \__fp_sin_series:NNwww #1#2#3 . #4; #5; { \__fp_fixed_mul:wwn #4; #4; { - \exp_after:wN \__fp_sin_series_aux:Nnww + \exp_after:wN \__fp_sin_series_aux:NNnww + \exp_after:wN #1 \__int_value:w \if_int_odd:w \__int_eval:w ( #3 + \c_two ) / \c_four \__int_eval_end: #2 @@ -4019,49 +4072,49 @@ } #4 ; } -\cs_new:Npn \__fp_sin_series_aux:Nnww #1#2 #3; #4; +\cs_new:Npn \__fp_sin_series_aux:NNnww #1#2#3 #4; #5; { - \if_int_odd:w \__int_eval:w #2 / \c_two \__int_eval_end: + \if_int_odd:w \__int_eval:w #3 / \c_two \__int_eval_end: \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: - { - \__fp_fixed_continue:wn {0000}{0000}{0000}{0001}{5619}{2070}; % 1/18! - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0000}{0000}{0477}{9477}{3324}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0000}{0011}{4707}{4559}{7730}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0000}{2087}{6756}{9878}{6810}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0027}{5573}{1922}{3985}{8907}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{2480}{1587}{3015}{8730}{1587}; - \__fp_fixed_mul_sub_back:wwwn #3; {0013}{8888}{8888}{8888}{8888}{8889}; - \__fp_fixed_mul_sub_back:wwwn #3; {0416}{6666}{6666}{6666}{6666}{6667}; - \__fp_fixed_mul_sub_back:wwwn #3; {5000}{0000}{0000}{0000}{0000}{0000}; - \__fp_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000}; + { % 1/18! + \__fp_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0001}{5619}{2070}; + #4; {0000}{0000}{0000}{0477}{9477}{3324}; + \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0000}{0011}{4707}{4559}{7730}; + \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0000}{2087}{6756}{9878}{6810}; + \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0027}{5573}{1922}{3985}{8907}; + \__fp_fixed_mul_sub_back:wwwn #4; {0000}{2480}{1587}{3015}{8730}{1587}; + \__fp_fixed_mul_sub_back:wwwn #4; {0013}{8888}{8888}{8888}{8888}{8889}; + \__fp_fixed_mul_sub_back:wwwn #4; {0416}{6666}{6666}{6666}{6666}{6667}; + \__fp_fixed_mul_sub_back:wwwn #4; {5000}{0000}{0000}{0000}{0000}{0000}; + \__fp_fixed_mul_sub_back:wwwn #4;{10000}{0000}{0000}{0000}{0000}{0000}; } - { - \__fp_fixed_continue:wn {0000}{0000}{0000}{0028}{1145}{7254}; % 1/17! - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0000}{0000}{7647}{1637}{3182}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0000}{0160}{5904}{3836}{8216}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0002}{5052}{1083}{8544}{1719}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0275}{5731}{9223}{9858}{9065}; - \__fp_fixed_mul_sub_back:wwwn #3; {0001}{9841}{2698}{4126}{9841}{2698}; - \__fp_fixed_mul_sub_back:wwwn #3; {0083}{3333}{3333}{3333}{3333}{3333}; - \__fp_fixed_mul_sub_back:wwwn #3; {1666}{6666}{6666}{6666}{6666}{6667}; - \__fp_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000}; - \__fp_fixed_mul:wwn #4; + { % 1/17! + \__fp_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0028}{1145}{7254}; + #4; {0000}{0000}{0000}{7647}{1637}{3182}; + \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0000}{0160}{5904}{3836}{8216}; + \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0002}{5052}{1083}{8544}{1719}; + \__fp_fixed_mul_sub_back:wwwn #4; {0000}{0275}{5731}{9223}{9858}{9065}; + \__fp_fixed_mul_sub_back:wwwn #4; {0001}{9841}{2698}{4126}{9841}{2698}; + \__fp_fixed_mul_sub_back:wwwn #4; {0083}{3333}{3333}{3333}{3333}{3333}; + \__fp_fixed_mul_sub_back:wwwn #4; {1666}{6666}{6666}{6666}{6666}{6667}; + \__fp_fixed_mul_sub_back:wwwn #4;{10000}{0000}{0000}{0000}{0000}{0000}; + \__fp_fixed_mul:wwn #5; } { \exp_after:wN \__fp_sanitize:Nw - \exp_after:wN #1 - \int_use:N \__int_eval:w \__fp_fixed_to_float:wN + \exp_after:wN #2 + \int_use:N \__int_eval:w #1 } - #1 + #2 } -\cs_new:Npn \__fp_tan_series:NNwww #1#2#3. #4; #5; +\cs_new:Npn \__fp_tan_series_o:NNwww #1#2#3. #4; #5; { \__fp_fixed_mul:wwn #4; #4; { - \exp_after:wN \__fp_tan_series_aux:Nnww + \exp_after:wN \__fp_tan_series_aux_o:Nnww \__int_value:w \if_int_odd:w \__int_eval:w #3 / \c_two \__int_eval_end: \exp_after:wN \reverse_if:N @@ -4071,18 +4124,18 @@ } #4 ; } -\cs_new:Npn \__fp_tan_series_aux:Nnww #1 #2 #3; #4; +\cs_new:Npn \__fp_tan_series_aux_o:Nnww #1 #2 #3; #4; { - \__fp_fixed_continue:wn {0000}{0000}{1527}{3493}{0856}{7059}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{0159}{6080}{0274}{5257}{6472}; + \__fp_fixed_mul_sub_back:wwwn {0000}{0000}{1527}{3493}{0856}{7059}; + #3; {0000}{0159}{6080}{0274}{5257}{6472}; \__fp_fixed_mul_sub_back:wwwn #3; {0002}{4571}{2320}{0157}{2558}{8481}; \__fp_fixed_mul_sub_back:wwwn #3; {0115}{5830}{7533}{5397}{3168}{2147}; \__fp_fixed_mul_sub_back:wwwn #3; {1929}{8245}{6140}{3508}{7719}{2982}; \__fp_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000}; \__fp_fixed_mul:wwn #4; { - \__fp_fixed_continue:wn {0000}{0007}{0258}{0681}{9408}{4706}; - \__fp_fixed_mul_sub_back:wwwn #3; {0000}{2343}{7175}{1399}{6151}{7670}; + \__fp_fixed_mul_sub_back:wwwn {0000}{0007}{0258}{0681}{9408}{4706}; + #3; {0000}{2343}{7175}{1399}{6151}{7670}; \__fp_fixed_mul_sub_back:wwwn #3; {0019}{2638}{4588}{9232}{8861}{3691}; \__fp_fixed_mul_sub_back:wwwn #3; {0536}{6357}{0691}{4344}{6852}{4252}; \__fp_fixed_mul_sub_back:wwwn #3; {5263}{1578}{9473}{6842}{1052}{6315}; @@ -4350,6 +4403,21 @@ \cs_new_eq:NN \fp_eval:n \fp_to_decimal:n \cs_new:Npn \fp_abs:n #1 { \fp_to_decimal:n { abs \__fp_parse:n {#1} } } +\cs_new:Npn \__fp_array_to_clist:n #1 + { + \__fp_array_to_clist_i:wwww ; + #1 + \__fp_array_to_clist_ii:ww \s__fp ; @ + ; , ~ , ~ @ \s_stop + } +\cs_new:Npn \__fp_array_to_clist_i:wwww #1; #2 \s__fp #3; #4 @ + { + #2 + \exp_after:wN \__fp_array_to_clist_i:wwww + \tex_romannumeral:D -`0 \__fp_to_tl:w \s__fp #3 ; ; + #4 , ~ #1 @ + } +\cs_new:Npn \__fp_array_to_clist_ii:ww #1 ; , ~ , ~ #2 @ #3 \s_stop {#2} %% %% File: l3fp-assign.dtx Copyright (C) 2011-2012 The LaTeX3 project %% @@ -4421,7 +4489,14 @@ \cs_generate_variant:Nn \fp_sub:Nn { c } \cs_generate_variant:Nn \fp_gsub:Nn { c } \cs_new_protected:Npn \fp_show:N #1 - { \__msg_show_variable:x { > \fp_to_tl:N #1 } } + { + \fp_if_exist:NTF #1 + { \__msg_show_variable:x { > \fp_to_tl:N #1 } } + { + \__msg_kernel_error:nnx { kernel } { variable-not-defined } + { \token_to_str:N #1 } + } + } \cs_new_protected:Npn \fp_show:n #1 { \__msg_show_variable:x { > \fp_to_tl:n {#1} } } \cs_generate_variant:Nn \fp_show:N { c } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3int.sty b/Master/texmf-dist/tex/latex/l3kernel/l3int.sty index 531f0a0e7c9..25667fc8c75 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3int.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3int.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3int.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3int.dtx 4121 2012-08-17 01:36:30Z bruno $ {L3 Integers} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -329,11 +329,11 @@ } \cs_new:Npn \int_until_do:nNnn #1#2#3#4 { - \int_compare:nNnF {#1} #2 {#3} - { - #4 - \int_until_do:nNnn {#1} #2 {#3} {#4} - } + \int_compare:nNnF {#1} #2 {#3} + { + #4 + \int_until_do:nNnn {#1} #2 {#3} {#4} + } } \cs_new:Npn \int_do_while:nNnn #1#2#3#4 { diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty b/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty index 3845880de85..0d717006172 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3msg.dtx 4077 2012-08-10 23:30:52Z bruno $ +\GetIdInfo$Id: l3msg.dtx 4147 2012-08-28 10:27:33Z bruno $ {L3 Messages} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -591,7 +591,7 @@ \c_msg_coding_error_text_tl Code-level~functions~must~contain~':'~to~separate~the~ argument~specification~from~the~function~name.~This~is~ - needed~when~defining~conditionals~or~when~building~a~ + needed~when~defining~conditionals~or~variants,~or~when~building~a~ parameter~text~from~the~number~of~arguments~of~the~function. } \__msg_kernel_new:nnnn { kernel } { protected-predicate } @@ -630,6 +630,14 @@ with~a~signature~starting~with~'#1',~but~that~is~longer~than~ the~signature~(part~after~the~colon)~of~'#2'. } +\__msg_kernel_new:nnnn { kernel } { invalid-variant } + { Variant~form~'#1'~invalid~for~base~form~'#2'. } + { + \c_msg_coding_error_text_tl + LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~ + with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~ + from~type~'#3'~to~type~'#4'. + } \__msg_kernel_new:nnn { kernel } { bad-variable } { Erroneous~variable~#1 used! } \__msg_kernel_new:nnn { kernel } { misused-sequence } @@ -736,7 +744,7 @@ \cs_if_exist:NTF #1 { \__msg_term:nnn { LaTeX / kernel } { show- #2 } {#1} - \__msg_show_variable:x {#3} + \__msg_show_variable:x { \tl_to_str:n {#3} } } { \__msg_kernel_error:nnx { kernel } { variable-not-defined } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty b/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty index 22fa6688784..93ef25ee4b6 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3prg.dtx 4061 2012-08-08 15:19:07Z bruno $ +\GetIdInfo$Id: l3prg.dtx 4114 2012-08-16 01:57:02Z bruno $ {L3 Control structures} %% \ProvidesExplPackage @@ -106,8 +106,8 @@ \cs_new_protected:Npn \bool_show:n #1 { \bool_if:nTF {#1} - { \__msg_show_variable:x { > true } } - { \__msg_show_variable:x { > false } } + { \__msg_show_variable:n { > true } } + { \__msg_show_variable:n { > false } } } \cs_generate_variant:Nn \bool_show:N { c } \bool_new:N \l_tmpa_bool diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty b/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty index e65ebc5e2bc..1e692963872 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3prop.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3prop.dtx 4092 2012-08-14 14:04:41Z bruno $ {L3 Property lists} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -295,9 +295,7 @@ { \__prg_map_break:Nn \prop_map_break: } \cs_new_protected:Npn \prop_show:N #1 { - \__msg_show_variable:Nnn - #1 - { prop } + \__msg_show_variable:Nnx #1 { prop } { \prop_map_function:NN #1 \__msg_show_item:nn } } \cs_generate_variant:Nn \prop_show:N { c } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty b/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty index 5b4fe8c3790..58e3b205359 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3seq.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3seq.dtx 4092 2012-08-14 14:04:41Z bruno $ {L3 Sequences and stacks} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -433,9 +433,7 @@ \prg_new_eq_conditional:NNn \seq_gpop:cN \seq_gpop_left:cN { T , F , TF } \cs_new_protected:Npn \seq_show:N #1 { - \__msg_show_variable:Nnn - #1 - { seq } + \__msg_show_variable:Nnx #1 { seq } { \seq_map_function:NN #1 \__msg_show_item:n } } \cs_generate_variant:Nn \seq_show:N { c } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty b/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty index 8888a5b9056..adbdbc68d8c 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty @@ -47,7 +47,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3skip.dtx 3991 2012-07-16 19:00:35Z joseph $ +\GetIdInfo$Id: l3skip.dtx 4121 2012-08-17 01:36:30Z bruno $ {L3 Dimensions and skips} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} |