summaryrefslogtreecommitdiff
path: root/Master/texmf-dist
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-09-15 23:59:34 +0000
committerKarl Berry <karl@freefriends.org>2010-09-15 23:59:34 +0000
commitffc97a564cf025403b74b69c48bc158f39145c9b (patch)
tree91831ffc43db63577e6b226bdb995a17ee84f251 /Master/texmf-dist
parent0ee0a7585d0a3abd4d2e0b604f8b5afec32e4a9c (diff)
expl3 2020 (14sep10)
git-svn-id: svn://tug.org/texlive/trunk@19747 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r--Master/texmf-dist/doc/latex/expl3/README41
-rw-r--r--Master/texmf-dist/doc/latex/expl3/expl3.pdfbin498620 -> 497961 bytes
-rw-r--r--Master/texmf-dist/doc/latex/expl3/l3calc.pdfbin377264 -> 377264 bytes
-rw-r--r--Master/texmf-dist/doc/latex/expl3/source3.pdfbin1461660 -> 1506021 bytes
-rw-r--r--Master/texmf-dist/doc/latex/expl3/source3.tex353
-rw-r--r--Master/texmf-dist/source/latex/expl3/expl3.dtx6
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3basics.dtx4
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3box.dtx52
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3clist.dtx126
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3doc.dtx6
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3expan.dtx4
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3fp.dtx3916
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3prg.dtx147
-rw-r--r--Master/texmf-dist/tex/latex/expl3/expl3.sty6
-rw-r--r--Master/texmf-dist/tex/latex/expl3/l3basics.sty4
-rw-r--r--Master/texmf-dist/tex/latex/expl3/l3box.sty7
-rw-r--r--Master/texmf-dist/tex/latex/expl3/l3clist.sty50
-rw-r--r--Master/texmf-dist/tex/latex/expl3/l3doc.cls6
-rw-r--r--Master/texmf-dist/tex/latex/expl3/l3expan.sty2
-rw-r--r--Master/texmf-dist/tex/latex/expl3/l3fp.sty2319
-rw-r--r--Master/texmf-dist/tex/latex/expl3/l3prg.sty86
21 files changed, 4909 insertions, 2226 deletions
diff --git a/Master/texmf-dist/doc/latex/expl3/README b/Master/texmf-dist/doc/latex/expl3/README
index 6a827490dad..4dd5ab22aa2 100644
--- a/Master/texmf-dist/doc/latex/expl3/README
+++ b/Master/texmf-dist/doc/latex/expl3/README
@@ -2,7 +2,7 @@
An Experimental LaTeX3 Programming Convention
=============================================
- 2009/08/02
+ 2010/08/18
WHERE TO GET IT
@@ -192,11 +192,6 @@ l3msg
Module providing a new mechanism to provide user messages.
-l3calc
-=====
-
-Module for using infix notation for the built-in register types
-(lengths and counters).
l3keyval
=====
@@ -210,6 +205,26 @@ Module for defining keys at a higher level than l3keyval; intended as
the main programmer's interface for creating keyval settings and
arguments.
+l3fp
+=====
+
+Module implementing floating point arithmetic. currently under develeopment
+
+l3luatex
+====
+
+
+=====================================================================
+
+Modules around by not included in expl3.sty (may vanish)
+
+l3calc
+=====
+
+Module for using infix notation for the built-in register types
+(lengths and counters).
+
+
=====================================================================
Install file
@@ -271,6 +286,18 @@ This typesets the documentation, then generates the index, and then
requires one or two more compilations to fully resolve the cross-references.
+interface3.tex
+==============
+
+Documentation of all interfaces but omitting the implementation of the
+commands. Still a large file!
+
+ pdflatex interface3
+ makeindex -s l3doc.ist -o interface3.ind interface3.idx
+ pdflatex interface3
+ pdflatex interface3
+
+
expl3.dtx
=========
@@ -280,5 +307,5 @@ explaining the basics of expl3 programming.
=====================================================================
---- Copyright 1998 -- 2009 The LaTeX3 Project. All rights reserved ---
+--- Copyright 1998-2010 The LaTeX3 Project. All rights reserved ---
diff --git a/Master/texmf-dist/doc/latex/expl3/expl3.pdf b/Master/texmf-dist/doc/latex/expl3/expl3.pdf
index d6843a90040..a7bd9773f65 100644
--- a/Master/texmf-dist/doc/latex/expl3/expl3.pdf
+++ b/Master/texmf-dist/doc/latex/expl3/expl3.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/expl3/l3calc.pdf b/Master/texmf-dist/doc/latex/expl3/l3calc.pdf
index 9fcf61288b7..652cce8cd20 100644
--- a/Master/texmf-dist/doc/latex/expl3/l3calc.pdf
+++ b/Master/texmf-dist/doc/latex/expl3/l3calc.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/expl3/source3.pdf b/Master/texmf-dist/doc/latex/expl3/source3.pdf
index 2b91c30f255..d3fa531e42a 100644
--- a/Master/texmf-dist/doc/latex/expl3/source3.pdf
+++ b/Master/texmf-dist/doc/latex/expl3/source3.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/expl3/source3.tex b/Master/texmf-dist/doc/latex/expl3/source3.tex
index 33ba1db3a99..74199936ca1 100644
--- a/Master/texmf-dist/doc/latex/expl3/source3.tex
+++ b/Master/texmf-dist/doc/latex/expl3/source3.tex
@@ -1,5 +1,5 @@
% \iffalse
-%% File: source3.dtx Copyright (C) 1990-2009 LaTeX3 project
+%% File: source3.dtx Copyright (C) 1990-2010 LaTeX3 project
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -33,356 +33,41 @@
%% -----------------------------------------------------------------------
%% \fi
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
% This document will typeset the LaTeX3 sources as a single document.
-% This will produce quite a large file (roughly ??? pages) and may
+% This will produce quite a large file (more than 400 pages) and may
% take a long time on a slow machine.
+%
+% There is also a shorter version (interface3.tex) that only typesets the
+% command % interface descriptions.
+%
+% Do not forget to generate the index (as explained on the terminal output
+% near the end of the run)!
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass{l3doc}
\listfiles
\begin{document}
+
\title{The \LaTeX3 Sources}
\author{\Team}
-
\pagenumbering{roman}
\maketitle
-\begin{abstract}
-
-\parindent=0pt
-\parskip=\baselineskip
-
-\noindent This is the reference documentation for the \pkg{expl3}
-programming environment. The \pkg{expl3} modules set up an experimental
-naming scheme for \LaTeX\ commands, which allow the \LaTeX\ programmer
-to systematically name functions and variables, and specify the argument
-types of functions.
-
-The \TeX\ and \eTeX\ primitives are all given a new name according to
-these conventions. However, in the main direct use of the primitives is
-not required or encouraged: the \pkg{expl3} modules define an
-independent low-level \LaTeX3 programming language.
-
-At present, the \pkg{expl3} modules are designed to be loaded on top of
-\LaTeXe. In time, a \LaTeX3 format will be produced based on this code.
-This allows the code to be used in \LaTeXe\ packages \emph{now} while a
-stand-alone \LaTeX3 is developed.
-
-\begin{bfseries}
- While \pkg{expl3} is still experimental, the bundle is now regarded as
- broadly stable. The syntax conventions and functions provided are now
- ready for wider use. There may still be changes to some functions, but
- these will be minor when compared to the scope of \pkg{expl3}.
-
- New modules will be added to the distributed version of \pkg{expl3} as
- they reach maturity.
-\end{bfseries}
-
-\end{abstract}
-
-\clearpage
-
-{\def\\{:}% fix "newlines" in the ToC
-\tableofcontents}
-
-\clearpage
-\pagenumbering{arabic}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-% Each of the following \DocInput lines includes a file with extension
-% .dtx. Each of these files may be typeset separately. For instance
-% pdflatex l3box.dtx
-% will typeset the source of the LaTeX3 box commands. If you use the
-% Makefile, the index will be generated automatically; e.g.,
-% make doc F=l3box
%
-% If this file is processed, each of these separate dtx files will be
-% contained as a part of a single document.
-
-\makeatletter
-\def\partname{Part}
-\def\maketitle{\part{\@title}}
-\let\thanks\@gobble
-\let\DelayPrintIndex\PrintIndex
-\let\PrintIndex\@empty
-\makeatother
-
-\part{Introduction to \pkg{expl3} and this document}
-
-This document is intended to act as a comprehensive reference manual
-for the \pkg{expl3} language. A general guide to the \LaTeX3
-programming language is found in \href{expl3.pdf}{expl3.pdf}.
-
-\section{Naming functions and variables}
-
-\LaTeX3 does not use \texttt{@} as a ``letter'' for defining
-internal macros. Instead, the symbols |_| and \texttt{:}
-are used in internal macro names to provide structure. The name of
-each \emph{function} is divided into logical units using \texttt{_},
-while \texttt{:} separates the \emph{name} of the function from the
-\emph{argument specifier} (``arg-spec''). This describes the arguments
-expected by the function. In most cases, each argument is represented
-by a single letter. The complete list of arg-spec letters for a function
-is referred to as the \emph{signature} of the function.
-
-Each function name starts with the \emph{module} to which it belongs.
-Thus apart from a small number of very basic functions, all \pkg{expl3}
-function names contain at least one underscore to divide the module
-name from the descriptive name of the function. For example, all
-functions concerned with comma lists are in module \texttt{clist} and
-begin \cs{clist_}.
-
-Every function must include an argument specifier. For functions which
-take no arguments, this will be blank and the function name will end
-\texttt{:}. Most functions take one or more arguments, and use the
-following argument specifiers:
-\begin{description}
- \item[\texttt{D}] The \texttt{D} specifier means \emph{do not use}.
- All of the \TeX\ primitives are initially \cs{let} to a \texttt{D}
- name, and some are then given a second name. Only the kernel
- team should use anything with a \texttt{D} specifier!
- \item[\texttt{N} and \texttt{n}] These mean \emph{no manipulation},
- of a single token for \texttt{N} and of a set of tokens given in
- braces for \texttt{n}. Both pass the argument though exactly as
- given. Usually, if you use a single token for an \texttt{n} argument,
- all will be well.
- \item[\texttt{c}] This means \emph{csname}, and indicates that the
- argument will be turned into a csname before being used. So
- So \cs{foo:c} |{ArgumentOne}| will act in the same way as \cs{foo:N}
- \cs{ArgumentOne}.
- \item[\texttt{V} and \texttt{v}] These mean \emph{value
- of variable}. The \texttt{V} and \texttt{v} specifiers are used to
- get the content of a variable without needing to worry about the
- underlying \TeX\ structure containing the data. A \texttt{V}
- argument will be a single token (similar to \texttt{N}), for example
- \cs{foo:V} \cs{MyVariable}; on the other hand, using \texttt{v} a
- csname is constructed first, and then the value is recovered, for
- example \cs{foo:v} |{MyVariable}|.
- \item[\texttt{o}] This means \emph{expansion once}. In general, the
- \texttt{V} and \texttt{v} specifiers are favoured over \texttt{o}
- for recovering stored information. However, \texttt{o} is useful
- for correctly processing information with delimited arguments.
- \item[\texttt{x}] The \texttt{x} specifier stands for \emph{exhaustive
- expansion}: the plain \TeX\ \cs{edef}.
- \item[\texttt{f}] The \texttt{f} specifier stands for \emph{full
- expansion}, and in contrast to \emph{x} stops at the first
- non-expandable item without trying to execute it.
- \item[\texttt{T} and \texttt{F}] For logic tests, there are the branch
- specifiers \texttt{T} (\emph{true}) and \texttt{F} (\emph{false}).
- Both specifiers treat the input in the same way as \texttt{n} (no
- change), but make the logic much easier to see.
- \item[\texttt{p}] The letter \texttt{p} indicates \TeX\
- \emph{parameters}. Normally this will be used for delimited
- functions as \pkg{expl3} provides better methods for creating simple
- sequential arguments.
- \item[\texttt{w}] Finally, there is the \texttt{w} specifier for
- \emph{weird} arguments. This covers everything else, but mainly
- applies to delimited values (where the argument must be terminated
- by some arbitrary string).
-\end{description}
-Notice that the argument specifier describes how the argument is
-processed prior to being passed to the underlying function. For example,
-\cs{foo:c} will take its argument, convert it to a control sequence and
-pass it to \cs{foo:N}.
-
-Variables are named in a similar manner to functions, but begin with
-a single letter to define the type of variable:
-\begin{description}
- \item[\texttt{c}] Constant: global parameters whose value should not
- be changed.
- \item[\texttt{g}] Parameters whose value should only be set globally.
- \item[\texttt{l}] Parameters whose value should only be set locally.
-\end{description}
-Each variable name is then build up in a similar way to that of a
-function, typically starting with the module\footnote{The module names are
- not used in case of generic scratch registers defined in the data
- type modules, e.g., the
- \texttt{int} module contains some scratch variables called \cs{l_tmpa_int},
- \cs{l_tmpb_int}, and so on. In such a case adding the module name up front
- to denote the module
- and in the back to indicate the type, as in
- \cs{l_int_tmpa_int} would be very unreadable.} name
-and then a descriptive part.
-Variables end with a short identifier to show the variable type:
-\begin{description}
- \item[\texttt{bool}] Either true or false.
- \item[\texttt{box}] Box register.
- \item[\texttt{clist}] Comma separated list.
- \item[\texttt{dim}] `Rigid' lengths.
- \item[\texttt{int}] Integer-valued count register.
- \item[\texttt{num}] A `fake' integer type using only macros. Useful for
- setting up allocation routines.
- \item[\texttt{prop}] Property list.
- \item[\texttt{skip}] `Rubber' lengths.
- \item[\texttt{seq}] `Sequence': a data-type used to implement lists
- (with access at both ends) and stacks.
- \item[\texttt{stream}] An input or output stream (for reading from or
- writing to, respectively).
- \item[\texttt{tl}] Token list variables: placeholder for a token list.
- \item[\texttt{toks}] Token register.
-\end{description}
-
-\subsubsection{Terminological inexactitude}
-
-A word of warning. In this document, and others referring to the \pkg{expl3}
-programming modules, we often refer to `variables' and `functions' as if
-they were actual constructs from a real programming language.
-In truth, \TeX\ is a macro processor, and functions are simply macros that
-may or mayn't take arguments and expand to their replacement text.
-Many of the common variables are \emph{also} macros, and if placed into the
-input stream will simply expand to their definition as well~--- a `function'
-with no arguments and a `token list variable' are in truth one and the same.
-On the other hand, some `variables' are actually registers that must be initialised and their values set and retreived with specific functions.
-
-The conventions of the \pkg{expl3} code are designed to clearly separate the
-ideas of `macros that contain data' and `macros that contain code', and a consistent wrapper is applied to all forms of `data' whether they be macros or actually registers.
-This means that sometimes we will use phrases like `the function returns a value', when actually we just mean `the macro expands to something'. Similarly, the term `execute' might be used in place of `expand' or it might refer to the more specific case of `processing in \TeX's stomach' (if you are familiar with the \TeX{}book parlance).
-
-If in doubt, please ask; chances are we've been hasty in writing certain definitions and need to be told to tighten up our terminology.
-
-\section{Documentation conventions}
-
-This document is typeset with the experimental \pkg{l3doc} class;
-several conventions are used to help describe the features of the code.
-A number of conventions are used here to make the documentation clearer.
-
-Each group of related functions is given in a box. For a function with
-a ``user'' name, this might read:
-\begin{function}{
- \ExplSyntaxOn |
- \ExplSyntaxOff
- }
- \begin{syntax}
- "\ExplSyntaxOn" \dots\ "\ExplSyntaxOff"
- \end{syntax}
- The textual description of how the function works would appear here. The
- syntax of the function is shown in mono-spaced text to the right of
- the box. In this example, the function takes no arguments and so the
- name of the function is simply reprinted.
-\end{function}
-
-For programming functions, which use \texttt{_} and \texttt{:} in their
-name there are a few additional conventions: If two related functions are given with identical names but
-different argument specifiers, these are termed \emph{variants} of each
-other, and the latter functions are printed in grey to show this more
-clearly. They will carry out the same function but will take different
-types of argument:
-\begin{function}{
- \seq_new:N |
- \seq_new:c
- }
- \begin{syntax}
- "\seq_new:N" <sequence>
- \end{syntax}
- When a number of variants are described, the arguments are usually
- illustrated only for the base function. Here, <sequence> indicates
- that \cs{seq_new:N} expects the name of a sequence. From the argument
- specifier, \cs{seq_new:c} also expects a sequence name, but as a
- name rather than as a control sequence. Each argument given in the
- illustration should be described in the following text.
-\end{function}
-
-Some functions are fully expandable, which allows it to be used within
-an \texttt{x}-type argument (in plain \TeX\ terms, inside an \cs{edef}).
-These fully expandable functions are indicated in the documentation by
-a star:
-\begin{function}{
- \cs_to_str:N / (EXP)
- }
- \begin{syntax}
- "\cs_to_str:N" <cs>
- \end{syntax}
- As with other functions, some text should follow which explains how
- the function works. Usually, only the star will indicate that the
- function is expandable. In this case, the function expects a <cs>,
- shorthand for a <control sequence>.
-\end{function}
-
-Conditional (\texttt{if}) functions are normally defined in three variants, with
-\texttt{T}, \texttt{F} and \texttt{TF} argument specifiers. This allows
-them to be used for different `true'/`false' branches, depending on
-which outcome the conditional is being used to test. To indicate this
-without repetition, this information is given in a shortened form:
-\begin{function}{
- \xetex_if_engine: / (TF) (EXP)
- }
- \begin{syntax}
- "\xetex_if_engine:TF" <true code> <false code>
- \end{syntax}
- The underlining and italic of \texttt{TF} indicates that
- \cs{xetex_if_engine:T}, \cs{xetex_if_engine:F} and
- \cs{xetex_if_engine:TF} are all available. Usually, the illustration
- will use the \texttt{TF} variant, and so both <true code>
- and <false code> will be shown. The two variant forms \texttt{T} and
- \texttt{F} take only <true code> and <false code>, respectively.
- Here, the star also shows that this function is expandable.
- With some minor exceptions, \emph{all} conditional functions in the
- \pkg{expl3} modules should be defined in this way.
-\end{function}
-
-Variables, constants and so on are described in a similar manner:
-\begin{variable}{
- \l_tmpa_tl
- }
- A short piece of text will describe the variable: there is no
- syntax illustration in this case.
-\end{variable}
-
-In some cases, the function is similar to one in \LaTeXe\ or plain \TeX.
-In these cases, the text will include an extra `\textbf{\TeX{}hackers
-note}' section:
-\begin{function}{
- \token_to_str:N / (EXP)
- }
- \begin{syntax}
- "\token_to_str:N" <token>
- \end{syntax}
- The normal description text.
- \begin{texnote}
- Detail for the experienced \TeX\ or \LaTeXe\ programmer. In this
- case, it would point out that this function is the \TeX\ primitive
- \cs{string}.
- \end{texnote}
-\end{function}
-
-\DisableImplementation
-
-\DocInput{l3names.dtx}
-
-\DocInput{l3basics.dtx}
-\DocInput{l3expan.dtx}
-\DocInput{l3prg.dtx}
-\DocInput{l3quark.dtx}
-\DocInput{l3token.dtx}
-
-\DocInput{l3int.dtx}
-\DocInput{l3intexpr.dtx}
-\DocInput{l3skip.dtx}
-
-\DocInput{l3tl.dtx}
-\DocInput{l3toks.dtx}
-\DocInput{l3seq.dtx}
-\DocInput{l3clist.dtx}
-\DocInput{l3prop.dtx}
-
-\DocInput{l3io.dtx}
-\DocInput{l3msg.dtx}
-\DocInput{l3box.dtx}
-\DocInput{l3xref.dtx}
-\DocInput{l3keyval.dtx}
-\DocInput{l3keys.dtx}
-%\DocInput{l3calc.dtx}
-\DocInput{l3file.dtx}
+% First load all modules and typeset the documentation parts
+%
-% \DocInput{l3precom.dtx}
-% \DocInput{l3alloc.dtx}
-% \DocInput{l3chk.dtx}
+\input{source3body} % all the individual modules
-\DocInput{l3fp.dtx}
-\DocInput{l3luatex.dtx}
+%
+% Now reload all modules and typeset the implementation parts
+%
\part{Implementation}
\def\maketitle{}
diff --git a/Master/texmf-dist/source/latex/expl3/expl3.dtx b/Master/texmf-dist/source/latex/expl3/expl3.dtx
index 0251c705b42..9657e07811e 100644
--- a/Master/texmf-dist/source/latex/expl3/expl3.dtx
+++ b/Master/texmf-dist/source/latex/expl3/expl3.dtx
@@ -37,7 +37,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: expl3.dtx 1987 2010-07-25 14:55:46Z joseph $
+\GetIdInfo$Id: expl3.dtx 2020 2010-09-14 10:37:46Z joseph $
{L3 Experimental code bundle wrapper}%
%\iffalse
%<*driver>
@@ -907,7 +907,7 @@
l3prop,
l3msg,
l3io,
- l3skip,
+ l3skip
}
% \end{macrocode}
% All the rest:
@@ -921,7 +921,7 @@
l3xref,
l3file,
l3fp,
- l3luatex,
+ l3luatex
}
\RequirePackage{calc}
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/expl3/l3basics.dtx b/Master/texmf-dist/source/latex/expl3/l3basics.dtx
index 99712ddc497..4bfc83ec33b 100644
--- a/Master/texmf-dist/source/latex/expl3/l3basics.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3basics.dtx
@@ -35,7 +35,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3basics.dtx 1942 2010-06-07 17:06:11Z will $
+\GetIdInfo$Id: l3basics.dtx 1992 2010-08-04 20:41:40Z joseph $
{L3 Experimental basic definitions}
%\iffalse
%<*driver>
@@ -2521,7 +2521,7 @@
% string between the two arguments.
% \begin{macrocode}
\cs_set:Npn \cs_tmp:w #1#2{
- \cs_new_nopar:Npn #1 { \exp_args:Nc #2 }
+ \cs_new_protected_nopar:Npn #1 { \exp_args:Nc #2 }
}
\cs_tmp:w \cs_set_nopar:cpn \cs_set_nopar:Npn
\cs_tmp:w \cs_set_nopar:cpx \cs_set_nopar:Npx
diff --git a/Master/texmf-dist/source/latex/expl3/l3box.dtx b/Master/texmf-dist/source/latex/expl3/l3box.dtx
index 6f3c0b21c1b..8da3021541b 100644
--- a/Master/texmf-dist/source/latex/expl3/l3box.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3box.dtx
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3box.dtx 1919 2010-05-22 05:56:38Z will $
+\GetIdInfo$Id: l3box.dtx 2015 2010-09-03 17:45:09Z mittelba $
{L3 Experimental Box module}
%\iffalse
%<*driver>
@@ -400,7 +400,18 @@
% "\vbox:n" \Arg{contents}
% \end{syntax}
% Places a "vbox" of natural size with baseline equal to the baseline
-% of the last line in the box.
+% of the last object in the box, i.e., if the last object is a line of text
+% the box has the same depth as that line; otherwise the depth will be zero.
+% \end{function}
+%
+% \begin{function}{%
+% \vbox_top:n |
+% }
+% \begin{syntax}
+% "\vbox_top:n" \Arg{contents}
+% \end{syntax}
+% Same as "\vbox:n" except that the reference point will be at the baseline
+% of the first object in the box not the last.
% \end{function}
%
% \begin{function}{%
@@ -413,7 +424,24 @@
% "\vbox_set:Nn" <box> \Arg{contents}
% \end{syntax}
% Sets <box> to be a vertical mode box containing \m{contents}. It has
-% its natural size. "\vbox_gset:Nn" does it globally.
+% its natural size and the reference point will be at the baseline of the
+% last object in the box. "\vbox_gset:Nn" does it globally.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \vbox_set_top:Nn |
+% \vbox_set_top:cn |
+% \vbox_gset_top:Nn |
+% \vbox_gset_top:cn |
+% }
+% \begin{syntax}
+% "\vbox_set_top:Nn" <box> \Arg{contents}
+% \end{syntax}
+% Sets <box> to be a vertical mode box containing \m{contents}. It has
+% its natural size (usually a small height and a larger depth)
+% and the reference point will be at the baseline of the
+% first object in the box. "\vbox_gset_top:Nn" does it globally.
% \end{function}
%
%
@@ -736,10 +764,12 @@
% \subsection{Vertical boxes}
%
%
-% \begin{macro}{\vbox:n}
+% \begin{macro}{\vbox:n,
+% \vbox_top:n}
% Put a vertical box directly into the input stream.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \vbox:n {\tex_vbox:D \scan_stop:}
+\cs_new_protected_nopar:Npn \vbox_top:n {\tex_vtop:D \scan_stop:}
% \end{macrocode}
% \end{macro}
%
@@ -755,6 +785,20 @@
% \end{macro}
% \end{macro}
%
+%
+% \begin{macro}{\vbox_set_top:Nn,\vbox_set_top:cn}
+% \begin{macro}{\vbox_gset_top:Nn,\vbox_gset_top:cn}
+% Storing material in a vertical box with a natural height and reference
+% point at the baseline of the first object in the box.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set_top:Nn #1#2 {\tex_setbox:D #1 \tex_vtop:D {#2}}
+\cs_generate_variant:Nn \vbox_set_top:Nn {cn}
+\cs_new_protected_nopar:Npn \vbox_gset_top:Nn {\pref_global:D \vbox_set_top:Nn}
+\cs_generate_variant:Nn \vbox_gset_top:Nn {cn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\vbox_set_to_ht:Nnn,\vbox_set_to_ht:cnn}
% \begin{macro}{\vbox_gset_to_ht:Nnn,\vbox_gset_to_ht:cnn,\vbox_gset_to_ht:ccn}
% Storing material in a vertical box with a specified height.
diff --git a/Master/texmf-dist/source/latex/expl3/l3clist.dtx b/Master/texmf-dist/source/latex/expl3/l3clist.dtx
index 4ae2d84d587..c3167477819 100644
--- a/Master/texmf-dist/source/latex/expl3/l3clist.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3clist.dtx
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3clist.dtx 1878 2010-03-29 07:15:02Z joseph $
+\GetIdInfo$Id: l3clist.dtx 1992 2010-08-04 20:41:40Z joseph $
{L3 Experimental comma separated lists}
%\iffalse
%<*driver>
@@ -875,103 +875,35 @@
%
% \subsection{Mapping}
%
-% \begin{macro}{\clist_map_function:NN}
-% \begin{macro}{\clist_map_function:cN}
-% \begin{macro}{\clist_map_function:nN}
-% |\clist_map_function:NN| \meta{comma-list} \meta{cmd} applies \meta{cmd} to each
-% element of \meta{comma-list}, from left to right.
+%\begin{macro}{\clist_map_function:NN}
+%\begin{macro}{\clist_map_function:Nc}
+%\begin{macro}{\clist_map_function:cN}
+%\begin{macro}{\clist_map_function:cc}
+%\begin{macro}{\clist_map_function:nN}
+%\begin{macro}{\clist_map_function:nc}
+%\begin{macro}{\clist_map_inline:Nn}
+%\begin{macro}{\clist_map_inline:cn}
+%\begin{macro}{\clist_map_inline:nn}
+%\begin{macro}{\clist_map_break:}
+% Using the above creating the comma mappings is easy..
% \begin{macrocode}
-\cs_new_nopar:Npn \clist_map_function:NN #1#2 {
- \clist_if_empty:NF #1 {
- \exp_after:wN \clist_map_function_aux:Nw
- \exp_after:wN #2 #1 , \q_recursion_tail , \q_recursion_stop
- }
-}
-\cs_generate_variant:Nn \clist_map_function:NN {cN}
-% \end{macrocode}
-% \begin{macrocode}
-\cs_new:Npn \clist_map_function:nN #1#2 {
- \tl_if_blank:nF {#1} {
- \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop
- }
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[aux]{\clist_map_function_aux:Nw}
-% The general loop. Tests if we hit the first stop marker and exits if
-% we did. If we didn't, place the function "#1" in front of the
-% element "#2", which is surrounded by braces.
-% \begin{macrocode}
-\cs_new:Npn \clist_map_function_aux:Nw #1#2,{
- \quark_if_recursion_tail_stop:n{#2}
- #1{#2}
- \clist_map_function_aux:Nw #1
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\clist_map_break:}
-% The break statement is easy. Same as in other modules, gobble
-% everything up to the special recursion stop marker.
-% \begin{macrocode}
-\cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\clist_map_inline:Nn}
-% \begin{macro}{\clist_map_inline:cn}
-% \begin{macro}{\clist_map_inline:nn}
-% The inline type is faster but not expandable. In order to make it
-% nestable, we use a counter to keep track of the nesting level so
-% that all of the functions called have distict names. A simpler
-% approach would of course be to use grouping and thus the save
-% stack but then you lose the ability to do things locally.
-%
-% A funny little thing occured in one document: The command setting
-% up the first call of |\clist_map_inline:Nn| was used in a tabular
-% cell and the inline code used |\\| so the loop broke as soon as
-% this happened. Lesson to be learned from this: If you wish to have
-% group like structure but not using the groupings of \TeX, then do
-% every operation globally.
-% \begin{macrocode}
-\int_new:N \g_clist_inline_level_int
-\cs_new_protected:Npn \clist_map_inline:Nn #1#2 {
- \clist_if_empty:NF #1 {
- \int_gincr:N \g_clist_inline_level_int
- \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
- ##1{#2}
-% \end{macrocode}
-% It is a lot more efficient to carry over
-% the special function rather than constructing the same csname over
-% and over again, so we just do it once. We reuse
-% |\clist_map_function_aux:Nw| for the actual loop.
-% \begin{macrocode}
- \exp_last_unbraced:NcV \clist_map_function_aux:Nw
- {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
- #1 , \q_recursion_tail , \q_recursion_stop
- \int_gdecr:N \g_clist_inline_level_int
- }
-}
-\cs_generate_variant:Nn \clist_map_inline:Nn {c}
-\cs_new_protected:Npn \clist_map_inline:nn #1#2 {
- \tl_if_empty:nF {#1} {
- \int_gincr:N \g_clist_inline_level_int
- \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
- ##1{#2}
- \exp_args:Nc \clist_map_function_aux:Nw
- {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
- #1 , \q_recursion_tail , \q_recursion_stop
- \int_gdecr:N \g_clist_inline_level_int
- }
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
+\prg_new_map_functions:Nn , { clist }
+\cs_generate_variant:Nn \clist_map_function:NN { Nc }
+\cs_generate_variant:Nn \clist_map_function:NN { c }
+\cs_generate_variant:Nn \clist_map_function:NN { cc }
+\cs_generate_variant:Nn \clist_map_inline:Nn { c }
+\cs_generate_variant:Nn \clist_map_inline:Nn { nc }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
%
% \begin{macro}{\clist_map_variable:nNn}
% \begin{macro}{\clist_map_variable:NNn}
diff --git a/Master/texmf-dist/source/latex/expl3/l3doc.dtx b/Master/texmf-dist/source/latex/expl3/l3doc.dtx
index df4cdf0ab5f..87bc748fb72 100644
--- a/Master/texmf-dist/source/latex/expl3/l3doc.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3doc.dtx
@@ -77,7 +77,7 @@ Do not distribute a modified version of this file.
% \end{macrocode}
%
%<*driver|class>
-\GetIdInfo$Id: l3doc.dtx 1987 2010-07-25 14:55:46Z joseph $
+\GetIdInfo$Id: l3doc.dtx 2004 2010-08-18 19:39:24Z joseph $
{L3 Experimental documentation class}
%</driver|class>
%
@@ -468,7 +468,7 @@ Do not distribute a modified version of this file.
% \begin{macrocode}
\LoadClass{article}
\RequirePackage{doc}
-\RequirePackage{array,alphalph,color,fixltx2e,enumitem,textcomp,trace,underscore}
+\RequirePackage{array,alphalph,booktabs,color,fixltx2e,enumitem,textcomp,trace,underscore}
% \end{macrocode}
%
% \begin{macrocode}
@@ -486,7 +486,7 @@ Do not distribute a modified version of this file.
\let\doc@verbatim\verbatim
\let\enddoc@verbatim\endverbatim
\let\doc@@verbatim\@verbatim
-\usepackage{verbatim}
+\RequirePackage{verbatim}
\AtBeginDocument{%
\let\verbatim\doc@verbatim
\let\endverbatim\enddoc@verbatim
diff --git a/Master/texmf-dist/source/latex/expl3/l3expan.dtx b/Master/texmf-dist/source/latex/expl3/l3expan.dtx
index e28b81baa32..270c9758238 100644
--- a/Master/texmf-dist/source/latex/expl3/l3expan.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3expan.dtx
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3expan.dtx 1948 2010-06-10 18:53:09Z joseph $
+\GetIdInfo$Id: l3expan.dtx 1991 2010-08-04 19:49:35Z joseph $
{L3 Experimental Argument Expansion module}
%\iffalse
%<*driver>
@@ -140,7 +140,7 @@
% same way. \cs{cs_generate_variant:Nn} can only be applied if the
% \meta{parent control sequence} is already defined. If the
% \meta{parent control sequence} is protected then the new sequence
-% will also be protected.
+% will also be protected. The variants are generated globally.
%\end{function}
%
% \paragraph{Internal functions} \mbox{}
diff --git a/Master/texmf-dist/source/latex/expl3/l3fp.dtx b/Master/texmf-dist/source/latex/expl3/l3fp.dtx
index bb64842ee90..54013130760 100644
--- a/Master/texmf-dist/source/latex/expl3/l3fp.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3fp.dtx
@@ -35,7 +35,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3fp.dtx 1985 2010-07-18 09:05:56Z joseph $
+\GetIdInfo$Id: l3fp.dtx 2021 2010-09-14 15:59:54Z joseph $
{L3 Experimental floating-point operations}
%\iffalse
%<*driver>
@@ -53,20 +53,29 @@
% \title{The \textsf{l3fp} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}\\
-% Fixed-point arithmetic}
+% Floating point arithmetic}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
%\begin{documentation}
%
-%\section{Fixed-point numbers}
-%
-% This module implements a fixed-point data type and arithmetic support.
-% Fixed-point numbers are real numbers with a fixed range of decimal
-% places available, in this case nine before and nine after the
-% decimal point. As this is a low-level module, error-checking is
-% minimal.
+%\section{Floating point numbers}
+%
+% A floating point number is one which is stored as a mantissa and
+% a separate exponent. This module implements arithmetic using radix
+% \( 10 \) floating point numbers. This means that the mantissa should
+% be a real number in the range \( 1 \le \string| x \string| < 10 \),
+% with the
+% exponent given as an integer between \( -99 \) and \( 99 \). In the
+% input, the exponent part is represented starting with an \texttt{e}.
+% As this is a low-level module, error-checking is minimal. Numbers
+% which are too large for the floating point unit to handle will result
+% in errors, either from \TeX\ or from \LaTeX. The \LaTeX\ code does not
+% check that the input will not overflow, hence the possibility of a
+% \TeX\ error. On the other hand, numbers which are too small will be
+% dropped, which will mean that extra decimal digits will simply be
+% lost.
%
% When parsing numbers, any missing parts will be interpreted as
% zero. So for example
@@ -77,38 +86,48 @@
%\end{verbatim}
% will all be interpreted as zero values without raising an error.
%
-% Number which are too large for the fixed-point unit to handle will
-% result in errors, either from \TeX\ or from \LaTeX. The \LaTeX\ code
-% does not check that the input will not overflow, hence the
-% possibility of a \TeX\ error. On the other hand, numbers which are too
-% small will be dropped, which will mean that extra decimal digits will
-% simply be lost.
-%
% Operations which give an undefined result (such as division by
-% \( 0 \)) or those which result in \( \pm \infty \) will not lead
-% to errors. Instead special marker values are returned, which
-% can be tested for using \cs{fp_if_undefined:N(TF)} and
-% \cs{fp_if_infinity:N(TF)}. In this way it is possible to work with
-% asymptopic functions without first checking the input. If these
+% \( 0 \)) will not lead to errors. Instead special marker values are
+% returned, which can be tested for using fr example
+% \cs{fp_if_undefined:N(TF)}. In this way it is possible to work with
+% asymptotic functions without first checking the input. If these
% special values are carried forward in calculations they will be
% treated as \( 0 \).
%
-% Fixed-point numbers are stored in the \texttt{fp} fixed-point
+% Floating point numbers are stored in the \texttt{fp} floating point
% variable type. This has a standard range of functions for
% variable management.
%
-%\subsection{Fixed-point variables}
+%\subsection{Constants}
+%
+%\begin{variable}{ \c_infinity_fp }
+% A marker value for an infinite result from a calculation, such as
+% \( \tan ( \pi / 2 ) \).
+%\end{variable}
+%
+%\begin{variable}{ \c_undefined_fp }
+% A special marker floating point variable representing the result of
+% an operation which does not give a defined result (such as division
+% by \( 0 \)).
+%\end{variable}
+%
+%\begin{variable}{ \c_zero_fp }
+% A permanently zero floating point variable.
+%\end{variable}
+%
+%\subsection{Floating-point variables}
%
%\begin{function}{
% \fp_new:N |
% \fp_new:c |
%}
% \begin{syntax}
-% \cs{fp_new:N} \meta{fixed-point}
+% \cs{fp_new:N} \meta{floating point variable}
% \end{syntax}
-% Creates a new \meta{fixed-point} or raises an error if the
-% name is already taken. The declaration global. The
-% \meta{fixed-point} will initially be set to "+0.000000000".
+% Creates a new \meta{floating point variable} or raises an error if
+% the name is already taken. The declaration global. The
+% \meta{floating point} will initially be set to "+0.000000000e0"
+% (the zero floating point).
%\end{function}
%
%\begin{function}{
@@ -118,10 +137,10 @@
% \fp_set_eq:cc |
%}
% \begin{syntax}
-% \cs{fp_set_eq:NN} \meta{fp1} \meta{fp2}
+% \cs{fp_set_eq:NN} \meta{fp var1} \meta{fp var2}
% \end{syntax}
-% Sets the value of \meta{fixed-point1} equal to that of
-% \meta{fixed-point2}. This assignment is restricted to the
+% Sets the value of \meta{floating point variable1} equal to that of
+% \meta{floating point variable2}. This assignment is restricted to the
% current \TeX\ group level.
%\end{function}
%
@@ -132,10 +151,10 @@
% \fp_gset_eq:cc |
%}
% \begin{syntax}
-% \cs{tl_gset_eq:NN} \meta{tl var1} \meta{tl var2}
+% \cs{fp_gset_eq:NN} \meta{fp var1} \meta{fp var2}
% \end{syntax}
-% Sets the value of \meta{fixed-point1} equal to that of
-% \meta{fixed-point2}. This assignment is global and so is
+% Sets the value of \meta{floating point variable1} equal to that of
+% \meta{floating point variable2}. This assignment is global and so is
% not limited by the current \TeX\ group level.
%\end{function}
%
@@ -144,10 +163,10 @@
% \fp_zero:c |
%}
% \begin{syntax}
-% \cs{fp_zero:N} \meta{fixed-point}
+% \cs{fp_zero:N} \meta{floating point variable}
% \end{syntax}
-% Sets the \meta{fixed-point} to "+0.000000000" within the current
-% scope.
+% Sets the \meta{floating point variable} to "+0.000000000e0" within
+% the current scope.
%\end{function}
%
%\begin{function}{
@@ -155,9 +174,9 @@
% \fp_gzero:c |
%}
% \begin{syntax}
-% \cs{fp_gzero:N} \meta{fixed-point}
+% \cs{fp_gzero:N} \meta{floating point variable}
% \end{syntax}
-% Sets the \meta{fixed-point} to "+0.000000000" globally.
+% Sets the \meta{floating point variable} to "+0.000000000e0" globally.
%\end{function}
%
%\begin{function}{
@@ -165,10 +184,10 @@
% \fp_set:cn |
%}
% \begin{syntax}
-% \cs{fp_set:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_set:Nn} \meta{floating point variable} \Arg{value}
% \end{syntax}
-% Sets the \meta{fixed-point} variable to \meta{value} within
-% the scope of the current \TeX\ group.
+% Sets the \meta{floating point variable} variable to \meta{value}
+% within the scope of the current \TeX\ group.
%\end{function}
%
%\begin{function}{
@@ -176,9 +195,10 @@
% \fp_gset:cn |
%}
% \begin{syntax}
-% \cs{fp_gset:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_gset:Nn} \meta{floating point variable} \Arg{value}
% \end{syntax}
-% Sets the \meta{fixed-point} variable to \meta{value} globally.
+% Sets the \meta{floating point variable} variable to \meta{value}
+% globally.
%\end{function}
%
%\begin{function}{
@@ -186,13 +206,13 @@
% \fp_set_from_dim:cn |
%}
% \begin{syntax}
-% \cs{fp_set_from_dim:Nn} \meta{fixed-point} \Arg{dimexpr}
+% \cs{fp_set_from_dim:Nn} \meta{floating point variable} \Arg{dimexpr}
% \end{syntax}
-% Sets the \meta{fixed-point} variable to the distance represented
+% Sets the \meta{floating point variable} to the distance represented
% by the \meta{dimension expression} in the units points. This means
% that distances given in other units are first converted to points
-% before being assigned to the \meta{fixed-point}. The assignment
-% is local.
+% before being assigned to the \meta{floating point variable}. The
+% assignment is local.
%\end{function}
%
%\begin{function}{
@@ -200,13 +220,34 @@
% \fp_gset_from_dim:cn |
%}
% \begin{syntax}
-% \cs{fp_gset_from_dim:Nn} \meta{fixed-point} \Arg{dimexpr}
+% \cs{fp_gset_from_dim:Nn} \meta{floating point variable} \Arg{dimexpr}
% \end{syntax}
-% Sets the \meta{fixed-point} variable to the distance represented
+% Sets the \meta{floating point variable} to the distance represented
% by the \meta{dimension expression} in the units points. This means
% that distances given in other units are first converted to points
-% before being assigned to the \meta{fixed-point}. The assignment
-% is global.
+% before being assigned to the \meta{floating point variable}. The
+% assignment is global.
+%\end{function}
+%
+%\begin{function}{
+% \fp_use:N / (EXP) |
+% \fp_use:c / (EXP) |
+%}
+% \begin{syntax}
+% \cs{fp_use:N} \meta{floating point variable}
+% \end{syntax}
+% Inserts the value of the \meta{floating point variable} into the
+% input stream. The value will be given as a real number without any
+% exponent part, and will always include a decimal point. For example,
+% \begin{verbatim}
+% \fp_new:Nn \test
+% \fp_set:Nn \test { 1.234 e 5 }
+% \fp_use:N \test
+% \end{verbatim}
+% will insert `\texttt{12345.00000}' into the input stream.
+% As illustrated, a floating point will always be inserted with ten
+% significant digits given. Very large and very small values will
+% include additional zeros for place value.
%\end{function}
%
%\begin{function}{
@@ -214,265 +255,131 @@
% \fp_show:c |
%}
% \begin{syntax}
-% \cs{fp_show:N} \meta{fixed-point}
+% \cs{fp_show:N} \meta{floating point variable}
% \end{syntax}
-% Displays the content of the \meta{fixed-point} on the
+% Displays the content of the \meta{floating point variable} on the
% terminal.
%\end{function}
%
-%\subsection{Unary operations}
+%\subsection{Conversion to other formats}
%
-% The unary operations alter the value stored within an \texttt{fp}
-% variable.
+% It is useful to be able to convert floating point variables to
+% other forms. These functions are expandable, so that the material
+% can be used in a variety of contexts. The \cs{fp_use:N} function
+% should also be consulted in this context, as it will insert the
+% value of the floating point variable as a real number.
%
%\begin{function}{
-% \fp_abs:N |
-% \fp_abs:c |
+% \fp_to_int:N / (EXP) |
+% \fp_to_int:c / (EXP) |
%}
% \begin{syntax}
-% \cs{fp_abs:N} \meta{fixed-point}
+% \cs{fp_to_int:N} \meta{floating point variable}
% \end{syntax}
-% Converts the \meta{fixed-point} to its absolute value, assigning
-% the result within the current \TeX\ group.
+% Inserts the integer value of the \meta{floating point variable}
+% into the input stream. The decimal part of the number will not be
+% included, but will be used to round the integer.
%\end{function}
%
%\begin{function}{
-% \fp_gabs:N |
-% \fp_gabs:c |
+% \fp_to_tl:N / (EXP) |
+% \fp_to_tl:c / (EXP) |
%}
% \begin{syntax}
-% \cs{fp_gabs:N} \meta{fixed-point}
+% \cs{fp_to_tl:N} \meta{floating point variable}
% \end{syntax}
-% Converts the \meta{fixed-point} to its absolute value, assigning
-% the result globally.
+% Inserts a representation of the \meta{floating point variable} into
+% the input stream as a token list. The representation follows the
+% conventions of a pocket calculator:
+% \begin{center}
+% \ttfamily
+% \begin{tabular}{r@{.}lr@{.}l}
+% \toprule
+% \multicolumn{2}{l}{\rmfamily{Floating point value}} &
+% \multicolumn{2}{l}{\rmfamily{Representation}} \\
+% \midrule
+% 1 & 234000000000e0 & 1 & 234 \\
+% -1 & 234000000000e0 & -1 & 234 \\
+% 1 & 234000000000e3 & \multicolumn{2}{l}{1234} \\
+% 1 & 234000000000e13 & \multicolumn{2}{l}{1234e13} \\
+% 1 & 234000000000e-1 & 0 & 1234 \\
+% 1 & 234000000000e-2 & 0 & 01234 \\
+% 1 & 234000000000e-3 & 1 & 234e-3 \\
+% \bottomrule
+% \end{tabular}
+% \end{center}
+% Notice that trailing zeros are removed in this process, and that
+% numbers which do not require a decimal part do \emph{not} include
+% a decimal marker.
%\end{function}
%
+%\subsection{Rounding floating point values}
+%
+% The module can round floating point values to either decimal places
+% or significant figures using the usual method in which exact halves
+% are rounded up.
+%
%\begin{function}{
-% \fp_neg:N |
-% \fp_neg:c |
+% \fp_round_figures:Nn |
+% \fp_round_figures:cn |
%}
% \begin{syntax}
-% \cs{fp_neg:N} \meta{fixed-point}
+% \cs{fp_round_figures:Nn} \meta{floating point variable} \Arg{target}
% \end{syntax}
-% Reverse the sign of the \meta{fixed-point}, assigning the result
-% within the current \TeX\ group.
+% Rounds the \meta{floating point variable} to the \meta{target} number
+% of significant figures (an integer expression). The rounding is
+% carried out locally.
%\end{function}
%
%\begin{function}{
-% \fp_gneg:N |
-% \fp_gneg:c |
+% \fp_ground_figures:Nn |
+% \fp_ground_figures:cn |
%}
% \begin{syntax}
-% \cs{fp_gneg:N} \meta{fixed-point}
+% \cs{fp_ground_figures:Nn} \meta{floating point variable} \Arg{target}
% \end{syntax}
-% Reverse the sign of the \meta{fixed-point}, assigning the result
-% globally.
+% Rounds the \meta{floating point variable} to the \meta{target} number
+% of significant figures (an integer expression). The rounding is
+% carried out globally.
%\end{function}
%
-%\subsection{Transferring \texttt{fp} to \texttt{tl} data}
-%
-% The highly-structured internal format used for \texttt{fp} data
-% will not generally be desirable for use in user output. As a result,
-% the module provides a set of intermediate level functions to convert
-% \texttt{fp} into \texttt{tl} material. This process is governed by
-% a number of settings, which determine how the output is rounded and
-% how trailing zeros are handled.
-%
%\begin{function}{
-% \fp_to_tl:NN |
-% \fp_to_tl:Nc |
-% \fp_to_tl:cN |
-% \fp_to_tl:cc |
+% \fp_round_places:Nn |
+% \fp_round_places:cn |
%}
% \begin{syntax}
-% \cs{fp_to_tl:NN} \meta{fixed-point} \meta{token list variable}
+% \cs{fp_round_places:Nn} \meta{floating point variable} \Arg{target}
% \end{syntax}
-% Transfers the content of the \meta{fixed-point} into the
-% \meta{token list variable}, formatting according to the currently
-% prevailing formatting settings. The \meta{token list variable} is
-% set within the current \TeX\ group.
+% Rounds the \meta{floating point variable} to the \meta{target} number
+% of decimal places (an integer expression). The rounding is
+% carried out locally.
%\end{function}
%
%\begin{function}{
-% \fp_gto_tl:NN |
-% \fp_gto_tl:Nc |
-% \fp_gto_tl:cN |
-% \fp_gto_tl:cc |
+% \fp_ground_places:Nn |
+% \fp_ground_places:cn |
%}
% \begin{syntax}
-% \cs{fp_gto_tl:NN} \meta{fixed-point} \meta{token list variable}
+% \cs{fp_ground_places:Nn} \meta{floating point variable} \Arg{target}
% \end{syntax}
-% Transfers the content of the \meta{fixed-point} into the
-% \meta{token list variable}, formatting according to the currently
-% prevailing formatting settings. The \meta{token list variable} is
-% set globally.
+% Rounds the \meta{floating point variable} to the \meta{target} number
+% of decimal places (an integer expression). The rounding is
+% carried out globally.
%\end{function}
%
-% The exact behaviour of the transfer process is governed by a small
-% family of key--value settings. These are accessible using the
-% \cs{keys_set:nn} function in the \texttt{fp} path:
-%\begin{verbatim}
-% \keys_set:nn { fp } {
-% % Settings here
-% }
-%\end{verbatim}
-%
-%\DescribeOption{remove-trailing-zeros}
-% The Boolean setting \texttt{remove-trailing-zeros} is used to govern
-% whether trailing zeros in the decimal part of the \texttt{fp} are
-% removed.
-%\begin{verbatim}
-% \fp_new:N \l_test_fp
-% \tl_new:N \l_test_tl
-% \fp_set:Nn \l_test_fp { 1.234 }
-% \keys_set:nn { fp } { remove-trailing-zeros = false }
-% \fp_to_tl \l_test_fp \l_test_tl % => '1.234000000'
-% \keys_set:nn { fp } { remove-trailing-zeros = true }
-% \fp_to_tl \l_test_fp \l_test_tl % => '1.234'
-%\end{verbatim}
-% Removing trailing zeros will always leave the result as a real number:
-%\begin{verbatim}
-% \fp_set:Nn \l_test_fp { 1.0 }
-% \keys_set:nn { fp } { remove-trailing-zeros = true }
-% \fp_to_tl \l_test_fp \l_test_tl % => '1.0'
-%\end{verbatim}
-%
-%\DescribeOption{round-mode}
-%\DescribeOption{precision}
-% The two options \texttt{round-mode} and \texttt{precision} determine
-% whether any rounding takes place for the decimal part of the output,
-% and if so how many significant output digits are retained. The
-% \texttt{precision} option indicates how many decimal digits should
-% be retained in the output, and therefore takes numerical values
-% only. The \texttt{round-mode} option takes one of the values
-% \texttt{none}, \texttt{truncate}, \texttt{half-from-zero} and
-% \texttt{half-even}. The \texttt{none} setting completely disables any
-% rounding, and therefore does not interact at all with
-% \texttt{precision}. The number of digits in the \texttt{tl} will
-% therefore depend only on the values in the \texttt{fp}, and whether
-% \texttt{remove-trailing-zeros} is active
-%\begin{verbatim}
-% \fp_set:Nn \l_test_fp { 1.234 }
-% \keys_set:nn { fp } {
-% round-mode = none ,
-% remove-trailing-zeros = false ,
-% }
-% \fp_to_tl \l_test_fp \l_test_tl % => '1.234000000'
-% \keys_set:nn { fp } {
-% round-mode = none ,
-% remove-trailing-zeros = true ,
-% }
-% \fp_to_tl \l_test_fp \l_test_tl % => '1.234'
-%\end{verbatim}
-% In all other cases (\texttt{truncate}, \texttt{half-from-zero}
-% and \texttt{half-even}) modification of the \texttt{fp} value will
-% always provide the number of decimal digits specified by
-% \texttt{precision}. This includes trailing zeros if they fall within
-% the \texttt{precision} requested. The \texttt{truncate} setting will
-% cause the transfer to simply discard excess decimal digits.
-%\begin{verbatim}
-% \keys_set:nn { fp } {
-% precision = 3 ,
-% remove-trailing-zeros = true ,
-% round-mode = truncate ,
-% }
-% \fp_set:Nn \l_test_fp { 1.23556 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.235
-% \fp_set:Nn \l_test_fp { 1.2 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.200
-%\end{verbatim}
-% The \texttt{half-from-zero} setting will round the number such that
-% if the digit to be rounded is \( 5 \) then rounding will occur
-% away from zero (increasing the absolute value).
-%\begin{verbatim}
-% \keys_set:nn { fp } {
-% precision = 3 ,
-% remove-trailing-zeros = true ,
-% round-mode = half-from-zero ,
-% }
-% \fp_set:Nn \l_test_fp { 1.23556 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.236
-% \fp_set:Nn \l_test_fp { 1.2358 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.236
-% \fp_set:Nn \l_test_fp { 1.23505 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.235
-% \fp_set:Nn \l_test_fp { -1.23556 }
-% \fp_to_tl \l_test_fp \l_test_tl % => -1.236
-% \fp_set:Nn \l_test_fp { -1.23 }
-% \fp_to_tl \l_test_fp \l_test_tl % => -1.230
-%\end{verbatim}
-% The alternative \texttt{half-even} setting behaves indentically to
-% \texttt{half-from-zero} apart from the case where the discarded number
-% is exctly half. In this special case the result is rounded to the
-% nearest even number in the final digit. This form of rounding is
-% sometimes used as it is does not add any bias to the final result.
-%\begin{verbatim}
-% \keys_set:nn { fp } {
-% precision = 3 ,
-% remove-trailing-zeros = true ,
-% round-mode = half-even ,
-% }
-% \fp_set:Nn \l_test_fp { 1.23556 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.236
-% \fp_set:Nn \l_test_fp { 1.23550 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.236
-% \fp_set:Nn \l_test_fp { 1.23450 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.234
-% \fp_set:Nn \l_test_fp { 1.234500001 }
-% \fp_to_tl \l_test_fp \l_test_tl % => 1.235
-%\end{verbatim}
-%
-%\subsection{Constants}
-%
-%\begin{variable}{ \c_zero_fp }
-% A permanently zero fixed-point variable.
-%\end{variable}
-%
-%\begin{variable}{ \c_undefined_fp }
-% A special marker fixed-point variable representing the result of
-% an operation which does not give a defined result (such as division
-% by \( 0 \)).
-%\end{variable}
-%
-%\begin{variable}{ \c_infinity_fp }
-% A special marker fixed-point variable representing \( \infty \).
-%\end{variable}
-%
-%\begin{variable}{ \c_minus_infinity_fp }
-% A special marker fixed-point variable representing \( -\infty \).
-%\end{variable}
-%
-%\subsection{Tests on fixed-point values}
+%\subsection{Tests on floating-point values}
%
%\begin{function}{
-% \fp_if_infinite_p:N / (EXP) |
-% \fp_if_infinite:N / (EXP) (TF) |
+% \fp_if_infinity_p:N / (EXP) |
+% \fp_if_infinity:N / (EXP) (TF) |
%}
% \begin{syntax}
-% \cs{fp_if_infinite_p:N} \meta{fixed-point}
-% \cs{fp_if_infinite:NTF} \meta{fixed-point}
+% \cs{fp_if_infinity_p:N} \meta{fixed-point}
+% \cs{fp_if_infinity:NTF} \meta{fixed-point}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if \meta{fixed-point} is infinite (\emph{i.e}.~equal to the
-% either of the special marker variables \cs{c_infinity_fp} or
-% \cs{c_minus_infinity_fp}). The branching versions then leave either
-% \meta{true code} or \meta{false code} in the input stream, as
-% appropriate to the truth of the test and the variant of the
-% function chosen. The logical truth of the test is left in the input
-% stream by the predicate version.
-%\end{function}
-%
-%\begin{function}{
-% \fp_if_plus_infinity_p:N / (EXP) |
-% \fp_if_plus_infinity:N / (EXP) (TF) |
-%}
-% \begin{syntax}
-% \cs{fp_if_plus_infinity_p:N} \meta{fixed-point}
-% \cs{fp_if_plus_infinity:NTF} \meta{fixed-point}
-% ~~\Arg{true code} \Arg{false code}
-% \end{syntax}
-% Tests if \meta{fixed-point} is \( +\infty \) (\emph{i.e}.~equal to
-% the special \cs{c_infinity_fp} variable). The branching versions then
+% Tests if \meta{floating point} is infinite (\emph{i.e}.~equal to the
+% special \cs{c_infinity_fp} variable). The branching versions then
% leave either \meta{true code} or \meta{false code} in the input
% stream, as appropriate to the truth of the test and the variant of
% the function chosen. The logical truth of the test is left in the
@@ -480,23 +387,6 @@
%\end{function}
%
%\begin{function}{
-% \fp_if_minus_infinity_p:N / (EXP) |
-% \fp_if_minus_infinity:N / (EXP) (TF) |
-%}
-% \begin{syntax}
-% \cs{fp_if_minus_infinity_p:N} \meta{fixed-point}
-% \cs{fp_if_minus_infinity:NTF} \meta{fixed-point}
-% ~~\Arg{true code} \Arg{false code}
-% \end{syntax}
-% Tests if \meta{fixed-point} is \( +\infty \) (\emph{i.e}.~equal to
-% the special \cs{c_minus_infinity_fp} variable). The branching
-% versions then leave either \meta{true code} or \meta{false code} in
-% the input stream, as appropriate to the truth of the test and the
-% variant of the function chosen. The logical truth of the test is left
-% in the input stream by the predicate version.
-%\end{function}
-%
-%\begin{function}{
% \fp_if_undefined_p:N / (EXP) |
% \fp_if_undefined:N / (EXP) (TF) |
%}
@@ -505,7 +395,7 @@
% \cs{fp_if_undefined:NTF} \meta{fixed-point}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if \meta{fixed-point} is undefined (\emph{i.e}.~equal to the
+% Tests if \meta{floating point} is undefined (\emph{i.e}.~equal to the
% special \cs{c_undefined_fp} variable). The branching versions then
% leave either \meta{true code} or \meta{false code} in the input
% stream, as appropriate to the truth of the test and the variant of
@@ -521,7 +411,7 @@
% \cs{fp_if_zero_p:N} \meta{fixed-point}
% \cs{fp_if_zero:NTF} \meta{fixed-point} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if \meta{fixed-point} is equal to zero (\emph{i.e}.~equal to
+% Tests if \meta{floating point} is equal to zero (\emph{i.e}.~equal to
% the special \cs{c_zero_fp} variable). The branching versions then
% leave either \meta{true code} or \meta{false code} in the input
% stream, as appropriate to the truth of the test and the variant of
@@ -539,12 +429,61 @@
% \cs{fp_compare:NNNTF} \Arg{fp1} \meta{relation} \Arg{fp2}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
-% Compares the two \meta{values} or \meta{fixed-points} based on the
+% Compares the two \meta{values} or \meta{floating points} based on the
% \meta{relation} (\texttt{=}, \verb"<" or \verb">"), and leaves
% either the \meta{true code} or \meta{false code} in the input stream,
% as appropriate to the truth of the test and the variant of the
-% function chosen. The tests treat undefined fixed-points
-% as zero, as the comparison is intended for real numbers only.
+% function chosen. The tests treat undefined floating points as zero,
+% as the comparison is intended for real numbers only.
+%\end{function}
+%
+%\subsection{Unary operations}
+%
+% The unary operations alter the value stored within an \texttt{fp}
+% variable.
+%
+%\begin{function}{
+% \fp_abs:N |
+% \fp_abs:c |
+%}
+% \begin{syntax}
+% \cs{fp_abs:N} \meta{floating point variable}
+% \end{syntax}
+% Converts the \meta{floating point variable} to its absolute value,
+% assigning the result within the current \TeX\ group.
+%\end{function}
+%
+%\begin{function}{
+% \fp_gabs:N |
+% \fp_gabs:c |
+%}
+% \begin{syntax}
+% \cs{fp_gabs:N} \meta{floating point variable}
+% \end{syntax}
+% Converts the \meta{floating point variable} to its absolute value,
+% assigning the result globally.
+%\end{function}
+%
+%\begin{function}{
+% \fp_neg:N |
+% \fp_neg:c |
+%}
+% \begin{syntax}
+% \cs{fp_neg:N} \meta{floating point variable}
+% \end{syntax}
+% Reverse the sign of the \meta{floating point variable}, assigning the
+% result within the current \TeX\ group.
+%\end{function}
+%
+%\begin{function}{
+% \fp_gneg:N |
+% \fp_gneg:c |
+%}
+% \begin{syntax}
+% \cs{fp_gneg:N} \meta{floating point variable}
+% \end{syntax}
+% Reverse the sign of the \meta{floating point variable}, assigning the
+% result globally.
%\end{function}
%
%\subsection{Arithmetic operations}
@@ -563,9 +502,9 @@
% \fp_add:cn |
%}
% \begin{syntax}
-% \cs{fp_add:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_add:Nn} \meta{floating point} \Arg{value}
% \end{syntax}
-% Adds the \meta{value} to the \meta{fixed-point}, making the
+% Adds the \meta{value} to the \meta{floating point}, making the
% assignment within the current \TeX\ group level.
%\end{function}
%
@@ -574,9 +513,9 @@
% \fp_gadd:cn |
%}
% \begin{syntax}
-% \cs{fp_gadd:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_gadd:Nn} \meta{floating point} \Arg{value}
% \end{syntax}
-% Adds the \meta{value} to the \meta{fixed-point}, making the
+% Adds the \meta{value} to the \meta{floating point}, making the
% assignment globally.
%\end{function}
%
@@ -585,9 +524,9 @@
% \fp_sub:cn |
%}
% \begin{syntax}
-% \cs{fp_sub:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_sub:Nn} \meta{floating point} \Arg{value}
% \end{syntax}
-% Subtracts the \meta{value} from the \meta{fixed-point}, making the
+% Subtracts the \meta{value} from the \meta{floating point}, making the
% assignment within the current \TeX\ group level.
%\end{function}
%
@@ -596,9 +535,9 @@
% \fp_gsub:cn |
%}
% \begin{syntax}
-% \cs{fp_gsub:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_gsub:Nn} \meta{floating point} \Arg{value}
% \end{syntax}
-% Subtracts the \meta{value} from the \meta{fixed-point}, making the
+% Subtracts the \meta{value} from the \meta{floating point}, making the
% assignment globally.
%\end{function}
%
@@ -607,9 +546,9 @@
% \fp_mul:cn |
%}
% \begin{syntax}
-% \cs{fp_mul:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_mul:Nn} \meta{floating point} \Arg{value}
% \end{syntax}
-% Multiples the \meta{fixed-point} by the \meta{value}, making the
+% Multiples the \meta{floating point} by the \meta{value}, making the
% assignment within the current \TeX\ group level.
%\end{function}
%
@@ -618,9 +557,9 @@
% \fp_gmul:cn |
%}
% \begin{syntax}
-% \cs{fp_gmul:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_gmul:Nn} \meta{floating point} \Arg{value}
% \end{syntax}
-% Multiples the \meta{fixed-point} by the \meta{value}, making the
+% Multiples the \meta{floating point} by the \meta{value}, making the
% assignment globally.
%\end{function}
%
@@ -629,11 +568,12 @@
% \fp_div:cn |
%}
% \begin{syntax}
-% \cs{fp_div:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_div:Nn} \meta{floating point} \Arg{value}
% \end{syntax}
-% Divides the \meta{fixed-point} by the \meta{value}, making the
+% Divides the \meta{floating point} by the \meta{value}, making the
% assignment within the current \TeX\ group level. If the \meta{value}
-% is zero, the \meta{fixed-point} will be set to \cs{c_undefined_fp}.
+% is zero, the \meta{floating point} will be set to
+% \cs{c_undefined_fp}.
%\end{function}
%
%\begin{function}{
@@ -641,20 +581,120 @@
% \fp_gdiv:cn |
%}
% \begin{syntax}
-% \cs{fp_gdiv:Nn} \meta{fixed-point} \Arg{value}
+% \cs{fp_gdiv:Nn} \meta{floating point} \Arg{value}
% \end{syntax}
-% Divides the \meta{fixed-point} by the \meta{value}, making the
+% Divides the \meta{floating point} by the \meta{value}, making the
% assignment globally. If the \meta{value} is zero, the
-% \meta{fixed-point} will be set to \cs{c_undefined_fp}.
+% \meta{floating point} will be set to \cs{c_undefined_fp}.
+%\end{function}
+%
+%\subsection{Trigonometric functions}
+%
+% The trigonometric functions all work in radians. They accept a maximum
+% input value of \( 1 000 000 000\), as there are issues with range
+% reduction and very large input values.
+%
+%\begin{function}{
+% \fp_sin:Nn |
+% \fp_sin:cn |
+%}
+% \begin{syntax}
+% \cs{fp_sin:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the sine of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% local.
+%\end{function}
+%
+%\begin{function}{
+% \fp_gsin:Nn |
+% \fp_gsin:cn |
+%}
+% \begin{syntax}
+% \cs{fp_gsin:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the sine of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% global.
+%\end{function}
+%
+%\begin{function}{
+% \fp_cos:Nn |
+% \fp_cos:cn |
+%}
+% \begin{syntax}
+% \cs{fp_cos:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the cosine of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% local.
+%\end{function}
+%
+%\begin{function}{
+% \fp_gcos:Nn |
+% \fp_gcos:cn |
+%}
+% \begin{syntax}
+% \cs{fp_gcos:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the cosine of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% global.
+%\end{function}
+%
+%\begin{function}{
+% \fp_tan:Nn |
+% \fp_tan:cn |
+%}
+% \begin{syntax}
+% \cs{fp_tan:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the tangent of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% local.
+%\end{function}
+%
+%\begin{function}{
+% \fp_gtan:Nn |
+% \fp_gtan:cn |
+%}
+% \begin{syntax}
+% \cs{fp_gtan:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the tangent of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% global.
%\end{function}
%
+%\subsection{Notes on the floating point unit}
+%
+% Anyone with experience of programming floating point calculations will
+% know that this is a complex area. The aim of the unit is to be
+% accurate enough for the likely applications in a typesetting context.
+% The arithmetic operations are therefore intended to provide ten digit
+% accuracy with the last digit accurate to \( \pm 1 \). The elemental
+% transcendental functions may not provide such high accuracy in every
+% case, although the design aim has been to provide \( 10 \) digit
+% accuracy for cases likely to be relevant in typesetting situations.
+% A good overview of the challenges in this area can be found in
+% J.-M.~Muller, \emph{Elementary functions: algorithms and
+% implementation}, 2nd edition, Birkh{\"a}uer Boston, New York, USA,
+% 2006.
+%
+% The internal representation of numbers is tuned to the needs of the
+% underlying \TeX\ system. This means that the format is somewhat
+% different from that used in, for example, computer floating point
+% units. Programming in \TeX\ makes it most convenient to use a
+% radix \( 10 \) system, using \TeX\ \texttt{count} registers for
+% storage and taking advantage where possible of delimited arguments.
+%
%\end{documentation}
%
%\begin{implementation}
%
%\section{Implementation}
%
-% Announce and ensure that the required packages are loaded.
+% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
%<*package>
\ProvidesExplPackage
@@ -664,50 +704,157 @@
%<*initex|package>
% \end{macrocode}
%
-% Internally, a fixed-point number is a token list variable of the
-% correct format. The first token in the variable is the sign: normally
-% this will be "+" or "-", but this token can also be used to indicate
-% a special state (for exampe if a calculation would give infinity as
-% a result). The main part of the number is then stored as a decimal:
-% there are always nine digits in the decimal part. This ensures that
-% two numbers which are equal to one another will always be stored in
-% the same way. For the same reason, zero is stored as "+0.000000000".
-%
-%\subsection{General variables}
-%
+%\subsection{Constants}
+%
+%\begin{macro}{\c_forty_four}
+%\begin{macro}{\c_one_hundred}
+%\begin{macro}{\c_one_thousand}
+%\begin{macro}{\c_one_million}
+%\begin{macro}{\c_one_hundred_million}
+%\begin{macro}{\c_five_hundred_million}
+%\begin{macro}{\c_one_thousand_million}
+% There is some speed to gain by moving numbers into fixed positions.
+% \begin{macrocode}
+\int_new:N \c_forty_four
+\int_set:Nn \c_forty_four { 44 }
+\int_new:N \c_one_hundred
+\int_set:Nn \c_one_hundred { 100 }
+\int_new:N \c_one_thousand
+\int_set:Nn \c_one_thousand { 1000 }
+\int_new:N \c_one_million
+\int_set:Nn \c_one_million { 1 000 000 }
+\int_new:N \c_one_hundred_million
+\int_set:Nn \c_one_hundred_million { 100 000 000 }
+\int_new:N \c_five_hundred_million
+\int_set:Nn \c_five_hundred_million { 500 000 000 }
+\int_new:N \c_one_thousand_million
+\int_set:Nn \c_one_thousand_million { 1 000 000 000 }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\c_fp_pi_by_four_decimal_int}
+%\begin{macro}{\c_fp_pi_by_four_extended_int}
+%\begin{macro}{\c_fp_pi_decimal_int}
+%\begin{macro}{\c_fp_pi_extended_int}
+%\begin{macro}{\c_fp_two_pi_decimal_int}
+%\begin{macro}{\c_fp_two_pi_extended_int}
+% Parts of \( \pi \) for trigonometric range reduction.
+% \begin{macrocode}
+\int_new:N \c_fp_pi_by_four_decimal_int
+\int_set:Nn \c_fp_pi_by_four_decimal_int { 785 398 158 }
+\int_new:N \c_fp_pi_by_four_extended_int
+\int_set:Nn \c_fp_pi_by_four_extended_int { 897 448 310 }
+\int_new:N \c_fp_pi_decimal_int
+\int_set:Nn \c_fp_pi_decimal_int { 141 592 653 }
+\int_new:N \c_fp_pi_extended_int
+\int_set:Nn \c_fp_pi_extended_int { 589 793 238 }
+\int_new:N \c_fp_two_pi_decimal_int
+\int_set:Nn \c_fp_two_pi_decimal_int { 283 185 307 }
+\int_new:N \c_fp_two_pi_extended_int
+\int_set:Nn \c_fp_two_pi_extended_int { 179 586 477 }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\c_infinity_fp}
+% Infinity is the biggest number that can be represented by \TeX's
+% \texttt{count} data type.
+% \begin{macrocode}
+\tl_new:N \c_infinity_fp
+\tl_set:Nn \c_infinity_fp { + 2147483647 . 2147483647 e 2147483647 }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\c_pi_fp}
+% The value \( \pi \), as a `machine number'.
+% \begin{macrocode}
+\tl_new:N \c_pi_fp
+\tl_set:Nn \c_pi_fp { + 3.141592654 e 0 }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\c_undefined_fp}
+% A marker for undefined values.
+% \begin{macrocode}
+\tl_new:N \c_undefined_fp
+\tl_set:Nn \c_undefined_fp { X 0.000000000 e 0 }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\c_zero_fp}
+% The constant zero value.
+% \begin{macrocode}
+\tl_new:N \c_zero_fp
+\tl_set:Nn \c_zero_fp { + 0.000000000 e 0 }
+% \end{macrocode}
+%\end{macro}
+%
+%\subsection{Variables}
+%
+%\begin{macro}{\l_fp_count_int}
+% A counter for things like the number of divisions possible.
+% \begin{macrocode}
+\int_new:N \l_fp_count_int
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_fp_div_offset_int}
+% When carrying out division, an offset is used for the results to
+% get the decimal part correct.
+% \begin{macrocode}
+\int_new:N \l_fp_div_offset_int
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_fp_input_a_sign_int}
%\begin{macro}{\l_fp_input_a_integer_int}
%\begin{macro}{\l_fp_input_a_decimal_int}
+%\begin{macro}{\l_fp_input_a_exponent_int}
+%\begin{macro}{\l_fp_input_b_sign_int}
%\begin{macro}{\l_fp_input_b_integer_int}
%\begin{macro}{\l_fp_input_b_decimal_int}
-% Storage for the input, divided into integer and decimal parts.
+%\begin{macro}{\l_fp_input_b_exponent_int}
+% Storage for the input: two storage areas as there are at most two
+% inputs.
% \begin{macrocode}
+\int_new:N \l_fp_input_a_sign_int
\int_new:N \l_fp_input_a_integer_int
\int_new:N \l_fp_input_a_decimal_int
+\int_new:N \l_fp_input_a_exponent_int
+\int_new:N \l_fp_input_b_sign_int
\int_new:N \l_fp_input_b_integer_int
\int_new:N \l_fp_input_b_decimal_int
+\int_new:N \l_fp_input_b_exponent_int
% \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
-%
-%\begin{macro}{\l_fp_input_a_sign_int}
-%\begin{macro}{\l_fp_input_b_sign_int}
-% The sign of each item in the input is stored as an \texttt{int} as
-% this allows some faster manipulation than would otherwise be possible.
-% \begin{macrocode}
-\int_new:N \l_fp_input_a_sign_int
-\int_new:N \l_fp_input_b_sign_int
-% \end{macrocode}
+%\end{macro}
+%\end{macro}
%\end{macro}
%\end{macro}
%
-%\begin{macro}{\l_fp_split_sign_int}
-% Used to speed up the sign-finding system.
+%\begin{macro}{\l_fp_input_a_extended_int}
+%\begin{macro}{\l_fp_input_b_extended_int}
+% For internal use, `extended' floating point numbers are
+% needed.
% \begin{macrocode}
-\int_new:N \l_fp_split_sign_int
+\int_new:N \l_fp_input_a_extended_int
+\int_new:N \l_fp_input_b_extended_int
% \end{macrocode}
%\end{macro}
+%\end{macro}
%
%\begin{macro}{\l_fp_mul_a_i_int}
%\begin{macro}{\l_fp_mul_a_ii_int}
@@ -721,10 +868,8 @@
%\begin{macro}{\l_fp_mul_b_iv_int}
%\begin{macro}{\l_fp_mul_b_v_int}
%\begin{macro}{\l_fp_mul_b_vi_int}
-% For multiplication, each number is split into six parts (three for the
-% decimal, three for the integer). So that they are a bt easier to keep
-% a track of these are simply numbered: i--iii are the integer and iv-vi
-% the decimal part.
+% Multiplication requires that the decimal part is split into parts
+% so that there are no overflows.
% \begin{macrocode}
\int_new:N \l_fp_mul_a_i_int
\int_new:N \l_fp_mul_a_ii_int
@@ -762,49 +907,60 @@
%\end{macro}
%\end{macro}
%
-%\begin{macro}{\l_fp_div_count_int}
-%\begin{macro}{\l_fp_div_offset_int}
-% Values used during division: an offset for small denominators and
-% a count for the actual division.
-% \begin{macrocode}
-\int_new:N \l_fp_div_count_int
-\int_new:N \l_fp_div_offset_int
-% \end{macrocode}
-%\end{macro}
-%\end{macro}
-%
%\begin{macro}{\l_fp_output_sign_int}
%\begin{macro}{\l_fp_output_integer_int}
%\begin{macro}{\l_fp_output_decimal_int}
+%\begin{macro}{\l_fp_output_exponent_int}
% Output is stored in the same way as input.
% \begin{macrocode}
\int_new:N \l_fp_output_sign_int
\int_new:N \l_fp_output_integer_int
\int_new:N \l_fp_output_decimal_int
+\int_new:N \l_fp_output_exponent_int
% \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_fp_output_extended_int}
+% Again, for calculations an extended part.
+% \begin{macrocode}
+\int_new:N \l_fp_output_extended_int
+% \end{macrocode}
+%\end{macro}
%
%\begin{macro}{\l_fp_round_carry_bool}
-%\begin{macro}{\l_fp_round_decimal_tl}
-%\begin{macro}{\l_fp_round_discard_int}
-%\begin{macro}{\l_fp_round_position_int}
-% The rounding system needs space to track carrying forward and also
-% to hold onto dicarded material (which may be relevant when rounding
-% to an even last digit). The current position in the decimal part also
-% needs to be tracked. For speed reasons, the decimal part of the number
-% is build back up in a token list when rounding, as this avoids
-% worrying about place value.
+% To indicate that a digit needs to be carried forward.
% \begin{macrocode}
\bool_new:N \l_fp_round_carry_bool
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_fp_round_decimal_tl}
+% A temporary store when rounding, to build up the decimal part without
+% needing to do any maths.
+% \begin{macrocode}
\tl_new:N \l_fp_round_decimal_tl
-\int_new:N \l_fp_round_discard_int
-\int_new:N \l_fp_round_position_int
% \end{macrocode}
%\end{macro}
+%
+%\begin{macro}{\l_fp_round_position_int}
+%\begin{macro}{\l_fp_round_target_int}
+% Used to check the position for rounding.
+% \begin{macrocode}
+\int_new:N \l_fp_round_position_int
+\int_new:N \l_fp_round_target_int
+% \end{macrocode}
%\end{macro}
%\end{macro}
+%
+%\begin{macro}{\l_fp_split_sign_int}
+% When splitting the input it is fastest to use a fixed name for the
+% sign part, and to transfer it after the split is complete.
+% \begin{macrocode}
+\int_new:N \l_fp_split_sign_int
+% \end{macrocode}
%\end{macro}
%
%\begin{macro}{\l_fp_tmp_int}
@@ -814,90 +970,154 @@
\int_new:N \l_fp_tmp_int
% \end{macrocode}
%\end{macro}
-%
+%
%\begin{macro}{\l_fp_tmp_tl}
-% The usual scratch token list.
+% A scratch token list variable for expanding material.
% \begin{macrocode}
\tl_new:N \l_fp_tmp_tl
% \end{macrocode}
%\end{macro}
%
-%\subsection{Constants}
-%
-%\begin{macro}{\c_zero_fp}
-% The constanct zero value.
+%\begin{macro}{\l_fp_trig_arg_tl}
+% A token list to store the formalised representation of the input
+% for trigonometry.
% \begin{macrocode}
-\tl_new:N \c_zero_fp
-\tl_set:Nn \c_zero_fp { + 0.000000000 }
+\tl_new:N \l_fp_trig_arg_tl
% \end{macrocode}
%\end{macro}
%
-%\begin{macro}{\c_undefined_fp}
-%\begin{macro}{\c_infinity_fp}
-%\begin{macro}{\c_minus_infinity_fp}
-% Special marker values for various mathematically-valid results which
-% are not fixed-point numbers.
+%\begin{macro}{\l_fp_trig_octant_int}
+% To track which octant the trigonometric input is in.
% \begin{macrocode}
-\tl_new:N \c_undefined_fp
-\tl_set:Nn \c_undefined_fp { X 0.000000000 }
-\tl_new:N \c_infinity_fp
-\tl_set:Nn \c_infinity_fp { +2147483647.2147483647 }
-\tl_new:N \c_minus_infinity_fp
-\tl_set:Nn \c_minus_infinity_fp { -2147483647.2147483647 }
+\int_new:N \l_fp_trig_octant_int
% \end{macrocode}
%\end{macro}
-%\end{macro}
-%\end{macro}
%
-%\begin{macro}{\c_one_hundred_million}
-%\begin{macro}{\c_one_thousand_million}
-% There is some speed to gain by moving numbers into fixed positions.
+%\begin{macro}{\l_fp_trig_sign_int}
+%\begin{macro}{\l_fp_trig_decimal_int}
+%\begin{macro}{\l_fp_trig_extended_int}
+% Used for the calculation of trigonometric values.
% \begin{macrocode}
-\int_new:N \c_one_hundred_million
-\int_set:Nn \c_one_hundred_million { 100000000 }
-\int_new:N \c_one_thousand_million
-\int_set:Nn \c_one_thousand_million { 1000000000 }
+\int_new:N \l_fp_trig_sign_int
+\int_new:N \l_fp_trig_decimal_int
+\int_new:N \l_fp_trig_extended_int
% \end{macrocode}
%\end{macro}
%\end{macro}
+%\end{macro}
%
-%\subsection{Tests for special values}
+%\subsection{Parsing numbers}
%
-%\begin{macro}{\fp_if_infinite_p:N}
-%\begin{macro}[TF]{\fp_if_infinite:N}
-%\begin{macro}{\fp_if_plus_infinity_p:N}
-%\begin{macro}[TF]{\fp_if_plus_infinity:N}
-%\begin{macro}{\fp_if_minus_infinity_p:N}
-%\begin{macro}[TF]{\fp_if_minus_infinity:N}
-% Testing for infinite values is complicated by the sign of infinity.
-% There are therefore three tests, one which will match \( +\infty \)
-% or \( -\infty \) and one test each for the two individual cases.
-% \begin{macrocode}
-\prg_new_conditional:Npnn \fp_if_infinite:N #1 { p , T , F , TF } {
- \tex_ifx:D #1 \c_infinity_fp
- \prg_return_true:
- \tex_else:D
- \tex_ifx:D #1 \c_minus_infinity_fp
- \prg_return_true:
- \tex_else:D
- \prg_return_false:
- \tex_fi:D
- \tex_fi:D
+%\begin{macro}{\fp_read:N}
+%\begin{macro}[aux]{\fp_read_aux:w}
+% Reading a stored value is made easier as the format is designed to
+% match the delimited function. This is always used to read the first
+% value (register "a").
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_read:N #1 {
+ \exp_after:wN \fp_read_aux:w #1 \q_stop
}
-\prg_new_conditional:Npnn \fp_if_plus_infinity:N #1 { p , T , F , TF } {
- \tex_ifx:D #1 \c_infinity_fp
- \prg_return_true:
+\cs_new_protected_nopar:Npn \fp_read_aux:w #1#2 . #3 e #4 \q_stop {
+ \tex_if:D #1 -
+ \l_fp_input_a_sign_int \c_minus_one
\tex_else:D
- \prg_return_false:
+ \l_fp_input_a_sign_int \c_one
\tex_fi:D
+ \l_fp_input_a_integer_int #2 \scan_stop:
+ \l_fp_input_a_decimal_int #3 \scan_stop:
+ \l_fp_input_a_exponent_int #4 \scan_stop:
}
-\prg_new_conditional:Npnn \fp_if_minus_infinity:N #1 { p , T , F , TF }
- {
- \tex_ifx:D #1 \c_minus_infinity_fp
- \prg_return_true:
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_split:Nn}
+%\begin{macro}[aux]{\fp_split_sign:}
+%\begin{macro}[aux]{\fp_split_exponent:}
+%\begin{macro}[aux]{\fp_split_aux_i:w}
+%\begin{macro}[aux]{\fp_split_aux_ii:w}
+%\begin{macro}[aux]{\fp_split_aux_iii:w}
+%\begin{macro}[aux]{\fp_split_decimal:w}
+%\begin{macro}[aux]{\fp_split_decimal_aux:w}
+% The aim here is to use as much of \TeX's mechanism as possible to pick
+% up the numerical input without any mistakes. In particular, negative
+% numbers have to be filtered out first in case the integer part is
+% \( 0 \) (in which case \TeX\ would drop the "-" sign). That process
+% has to be done in a loop for cases where the sign is repeated.
+% Finding an exponent is relatively easy, after which the next phase is
+% to find the integer part, which will terminate with a ".", and trigger
+% the decimal-finding code. The later will allow the decimal to be too
+% long, truncating the result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_split:Nn #1#2 {
+ \tl_set:Nx \l_fp_tmp_tl {#2}
+ \l_fp_split_sign_int \c_one
+ \fp_split_sign:
+ \use:c { l_fp_input_ #1 _sign_int } \l_fp_split_sign_int
+ \exp_after:wN \fp_split_exponent:w \l_fp_tmp_tl e e \q_stop #1
+}
+\cs_new_protected_nopar:Npn \fp_split_sign: {
+ \tex_ifnum:D \pdf_strcmp:D
+ { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { - }
+ = \c_zero
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN
+ \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
+ }
+ \l_fp_split_sign_int -\l_fp_split_sign_int
+ \exp_after:wN \fp_split_sign:
+ \tex_else:D
+ \tex_ifnum:D \pdf_strcmp:D
+ { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { + }
+ = \c_zero
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN
+ \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
+ }
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_split_sign:
+ \tex_fi:D
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_split_exponent:w #1 e #2 e #3 \q_stop #4 {
+ \use:c { l_fp_input_ #4 _exponent_int }
+ \etex_numexpr:D 0 #2 \scan_stop:
+ \tex_afterassignment:D \fp_split_aux_i:w
+ \use:c { l_fp_input_ #4 _integer_int }
+ \etex_numexpr:D 0 #1 . . \q_stop #4
+}
+\cs_new_protected_nopar:Npn \fp_split_aux_i:w #1 . #2 . #3 \q_stop {
+ \fp_split_aux_ii:w #2 000000000 \q_stop
+}
+\cs_new_protected_nopar:Npn \fp_split_aux_ii:w #1#2#3#4#5#6#7#8#9 {
+ \fp_split_aux_iii:w {#1#2#3#4#5#6#7#8#9}
+}
+\cs_new_protected_nopar:Npn \fp_split_aux_iii:w #1#2 \q_stop {
+ \l_fp_tmp_int 1 #1 \scan_stop:
+ \exp_after:wN \fp_split_decimal:w
+ \int_use:N \l_fp_tmp_int 000000000 \q_stop
+}
+\cs_new_protected_nopar:Npn \fp_split_decimal:w #1#2#3#4#5#6#7#8#9 {
+ \fp_split_decimal_aux:w {#2#3#4#5#6#7#8#9}
+}
+\cs_new_protected_nopar:Npn \fp_split_decimal_aux:w #1#2#3 \q_stop #4 {
+ \use:c { l_fp_input_ #4 _decimal_int } #1#2 \scan_stop:
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \use:c { l_fp_input_ #4 _integer_int } +
+ \use:c { l_fp_input_ #4 _decimal_int }
+ \scan_stop:
+ = \c_zero
+ \use:c { l_fp_input_ #4 _sign_int } \c_one
+ \tex_fi:D
+ \tex_ifnum:D
+ \use:c { l_fp_input_ #4 _integer_int } < \c_one_thousand_million
\tex_else:D
- \prg_return_false:
- \tex_fi:D
+ \exp_after:wN \fp_overflow_msg:
+ \tex_fi:D
}
% \end{macrocode}
%\end{macro}
@@ -906,39 +1126,178 @@
%\end{macro}
%\end{macro}
%\end{macro}
+%\end{macro}
+%\end{macro}
%
-%\begin{macro}{\fp_if_undefined_p:N}
-%\begin{macro}[TF]{\fp_if_undefined:N}
-% Testing for an undefined value is easy.
+%\begin{macro}{\fp_standardise:NNNN}
+%\begin{macro}[aux]{\fp_standardise_aux:NNNN}
+%\begin{macro}[aux]{\fp_standardise_aux:}
+%\begin{macro}[aux]{\fp_standardise_aux:w}
+% The idea here is to shift the input into a known exponent range. This
+% is done using \TeX\ tokens where possible, as this is faster than
+% arithmetic.
% \begin{macrocode}
-\prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF } {
- \tex_ifx:D #1 \c_undefined_fp
- \prg_return_true:
+\cs_new_protected_nopar:Npn \fp_standardise:NNNN #1#2#3#4 {
+ \tex_ifnum:D
+ \etex_numexpr:D #2 + #3 = \c_zero
+ #1 \c_one
+ #4 \c_zero
+ \exp_after:wN \use_none:nnnn
\tex_else:D
- \prg_return_false:
+ \exp_after:wN \fp_standardise_aux:NNNN
\tex_fi:D
+ #1#2#3#4
}
+\cs_new_protected_nopar:Npn \fp_standardise_aux:NNNN #1#2#3#4 {
+ \cs_set_protected_nopar:Npn \fp_standardise_aux:
+ {
+ \tex_ifnum:D #2 = \c_zero
+ \tex_advance:D #3 \c_one_thousand_million
+ \exp_after:wN \fp_standardise_aux:w
+ \int_use:N #3 \q_stop
+ \exp_after:wN \fp_standardise_aux:
+ \tex_fi:D
+ }
+ \cs_set_protected_nopar:Npn
+ \fp_standardise_aux:w ##1##2##3##4##5##6##7##8##9 \q_stop
+ {
+ #2 ##2 \scan_stop:
+ #3 ##3##4##5##6##7##8##9 0 \scan_stop:
+ \tex_advance:D #4 \c_minus_one
+ }
+ \fp_standardise_aux:
+ \cs_set_protected_nopar:Npn \fp_standardise_aux:
+ {
+ \tex_ifnum:D #2 > \c_nine
+ \tex_advance:D #2 \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_standardise_aux:w \int_use:N #2
+ \exp_after:wN \fp_standardise_aux:
+ \tex_fi:D
+ }
+ \cs_set_protected_nopar:Npn
+ \fp_standardise_aux:w ##1##2##3##4##5##6##7##8##9
+ {
+ #2 ##1##2##3##4##5##6##7##8 \scan_stop:
+ \tex_advance:D #3 \c_one_thousand_million
+ \tex_divide:D #3 \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ ##9
+ \exp_after:wN \use_none:n \int_use:N #3
+ }
+ #3 \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D #4 \c_one
+ }
+ \fp_standardise_aux:
+ \tex_ifnum:D #4 < \c_one_hundred
+ \tex_ifnum:D #4 > -\c_one_hundred
+ \tex_else:D
+ #1 \c_one
+ #2 \c_zero
+ #3 \c_zero
+ #4 \c_zero
+ \tex_fi:D
+ \tex_else:D
+ \exp_after:wN \fp_overflow_msg:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_standardise_aux: { }
+\cs_new_protected_nopar:Npn \fp_standardise_aux:w { }
% \end{macrocode}
%\end{macro}
%\end{macro}
+%\end{macro}
+%\end{macro}
%
-%\begin{macro}{\fp_if_zero_p:N}
-%\begin{macro}[TF]{\fp_if_zero:N}
-% Testing for a zero fixed-point is also easy.
+%\subsection{Internal utilities}
+%
+%\begin{macro}{\fp_level_input_exponents:}
+%\begin{macro}[aux]{\fp_level_input_exponents_a:}
+%\begin{macro}[aux]{\fp_level_input_exponents_a:NNNNNNNNN}
+%\begin{macro}[aux]{\fp_level_input_exponents_b:}
+%\begin{macro}[aux]{\fp_level_input_exponents_b:NNNNNNNNN}
+% The routines here are similar to those used to standardise the
+% exponent. However, the aim here is different: the two exponents need
+% to end up the same.
% \begin{macrocode}
-\prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF } {
- \tex_ifx:D #1 \c_zero_fp
- \prg_return_true:
+\cs_new_protected_nopar:Npn \fp_level_input_exponents: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \exp_after:wN \fp_level_input_exponents_a:
\tex_else:D
- \prg_return_false:
+ \exp_after:wN \fp_level_input_exponents_b:
\tex_fi:D
}
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_a: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \tex_advance:D \l_fp_input_b_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_level_input_exponents_a:NNNNNNNNN
+ \int_use:N \l_fp_input_b_integer_int
+ \exp_after:wN \fp_level_input_exponents_a:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_level_input_exponents_a:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \l_fp_input_b_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_input_b_decimal_int \c_one_thousand_million
+ \tex_divide:D \l_fp_input_b_decimal_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_b_decimal_int
+ }
+ \l_fp_input_b_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_b_exponent_int \c_one
+}
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_b: {
+ \tex_ifnum:D \l_fp_input_b_exponent_int > \l_fp_input_a_exponent_int
+ \tex_advance:D \l_fp_input_a_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_level_input_exponents_b:NNNNNNNNN
+ \int_use:N \l_fp_input_a_integer_int
+ \exp_after:wN \fp_level_input_exponents_b:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_level_input_exponents_b:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \l_fp_input_a_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \tex_divide:D \l_fp_input_a_decimal_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ }
+ \l_fp_input_a_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+}
% \end{macrocode}
%\end{macro}
%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_tmp:w}
+% Used for output of results, cutting down on \cs{exp_after:wN}.
+% This is just a place holder definition.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_tmp:w #1#2 { }
+% \end{macrocode}
+%\end{macro}
%
%\subsection{Operations for \texttt{fp} variables}
%
+% The format of \texttt{fp} variables is tightly defined, so that
+% they can be read quickly by the internal code. The format is a single
+% sign token, a single number, the decimal point, nine decimal numbers,
+% an "e" and finally the exponent. This final part may vary in length.
+% When stored, floating points will always be stored with a value in
+% the integer position unless the number is zero.
+%
%\begin{macro}{\fp_new:N}
%\begin{macro}{\fp_new:c}
% Fixed-points always have a value, and of course this has to be
@@ -992,21 +1351,31 @@
\cs_new_protected_nopar:Npn \fp_set_aux:NNn #1#2#3 {
\group_begin:
\fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
\tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
+ \cs_set_protected_nopar:Npx \fp_tmp:w
{
- \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
- -
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_input_a_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_input_a_decimal_int
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
}
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w
}
\cs_generate_variant:Nn \fp_set:Nn { c }
\cs_generate_variant:Nn \fp_gset:Nn { c }
@@ -1024,11 +1393,13 @@
%\begin{macro}[aux]{\fp_set_from_dim_aux:NNn}
%\begin{macro}[aux]{\fp_set_from_dim_aux:w}
%\begin{macro}{\l_fp_tmp_dim}
+%\begin{macro}{\l_fp_tmp_skip}
% Here, dimensions are converted to fixed-points \emph{via} a
% temporary variable. This ensures that they always convert as points.
% The code is then essentially the same as for \cs{fp_set:Nn}, but with
% the dimension passed so that it will be striped of the "pt" on the
-% way through.
+% way through. The passage through a skip is used to remove any rubber
+% part.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_set_from_dim:Nn {
\fp_set_from_dim_aux:NNn \tl_set:Nx
@@ -1038,27 +1409,38 @@
}
\cs_new_protected_nopar:Npn \fp_set_from_dim_aux:NNn #1#2#3 {
\group_begin:
- \l_fp_tmp_dim \etex_dimexpr:D #3 \scan_stop:
+ \l_fp_tmp_skip \etex_glueexpr:D #3 \scan_stop:
+ \l_fp_tmp_dim \l_fp_tmp_skip
\fp_split:Nn a
{
\exp_after:wN \fp_set_from_dim_aux:w
\dim_use:N \l_fp_tmp_dim
}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
\tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
+ \cs_set_protected_nopar:Npx \fp_tmp:w
{
- \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
- -
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_input_a_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_input_a_decimal_int
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
}
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w
}
\cs_set_protected_nopar:Npx \fp_set_from_dim_aux:w {
\cs_set_nopar:Npn \exp_not:N \fp_set_from_dim_aux:w
@@ -1068,6 +1450,7 @@
\cs_generate_variant:Nn \fp_set_from_dim:Nn { c }
\cs_generate_variant:Nn \fp_gset_from_dim:Nn { c }
\dim_new:N \l_fp_tmp_dim
+\skip_new:N \l_fp_tmp_skip
% \end{macrocode}
%\end{macro}
%\end{macro}
@@ -1076,6 +1459,7 @@
%\end{macro}
%\end{macro}
%\end{macro}
+%\end{macro}
%
%\begin{macro}{\fp_set_eq:NN}
%\begin{macro}{\fp_set_eq:cN}
@@ -1117,114 +1501,539 @@
%
%\begin{macro}{\fp_use:N}
%\begin{macro}{\fp_use:c}
-% These are token lists, so this is easy.
+%\begin{macro}[aux]{\fp_use_aux:w}
+%\begin{macro}[aux]{\fp_use_none:w}
+%\begin{macro}[aux]{\fp_use_small:w}
+%\begin{macro}[aux]{\fp_use_large:w}
+%\begin{macro}[aux]{\fp_use_large_aux_i:w}
+%\begin{macro}[aux]{\fp_use_large_aux_1:w}
+%\begin{macro}[aux]{\fp_use_large_aux_2:w}
+%\begin{macro}[aux]{\fp_use_large_aux_3:w}
+%\begin{macro}[aux]{\fp_use_large_aux_4:w}
+%\begin{macro}[aux]{\fp_use_large_aux_5:w}
+%\begin{macro}[aux]{\fp_use_large_aux_6:w}
+%\begin{macro}[aux]{\fp_use_large_aux_7:w}
+%\begin{macro}[aux]{\fp_use_large_aux_8:w}
+%\begin{macro}[aux]{\fp_use_large_aux_i:w}
+%\begin{macro}[aux]{\fp_use_large_aux_ii:w}
+% The idea of the \cs{fp_use:N} function to convert the stored
+% value into something suitable for \TeX\ to use as a number in an
+% expandable manner. The first step is to deal with the sign, then
+% work out how big the input is.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use:N #1 {
+ \exp_after:wN \fp_use_aux:w #1 \q_stop
+}
+\cs_generate_variant:Nn \fp_use:N { c }
+\cs_new_nopar:Npn \fp_use_aux:w #1#2 e #3 \q_stop {
+ \tex_if:D #1 -
+ -
+ \tex_fi:D
+ \tex_ifnum:D #3 > \c_zero
+ \exp_after:wN \fp_use_large:w
+ \tex_else:D
+ \tex_ifnum:D #3 < \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_use_small:w
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_use_none:w
+ \tex_fi:D
+ \tex_fi:D
+ #2 e #3 \q_stop
+}
+% \end{macrocode}
+% When the exponent is zero, the input is simply returned as output.
% \begin{macrocode}
-\cs_new_eq:NN \fp_use:N \tl_use:N
-\cs_new_eq:NN \fp_use:c \tl_use:c
+\cs_new_nopar:Npn \fp_use_none:w #1 e #2 \q_stop {#1}
+% \end{macrocode}
+% For small numbers (less than \( 1 \)) the correct number of zeros
+% have to be inserted, but the decimal point is easy.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use_small:w #1 . #2 e #3 \q_stop {
+ 0 .
+ \prg_replicate:nn { -#3 - 1 } { 0 }
+ #1#2
+}
+% \end{macrocode}
+% Life is more complex for large numbers. The decimal point needs to
+% be shuffled, with potentially some zero-filling for very large values.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use_large:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D #3 < \c_ten
+ \exp_after:wN \fp_use_large_aux_i:w
+ \tex_else:D
+ \exp_after:wN \fp_use_large_aux_ii:w
+ \tex_fi:D
+ #1#2 e #3 \q_stop
+}
+\cs_new_nopar:Npn \fp_use_large_aux_i:w #1#2 e #3 \q_stop {
+ #1
+ \use:c { fp_use_large_aux_ #3 :w } #2 \q_stop
+}
+\cs_new_nopar:cpn { fp_use_large_aux_1:w } #1#2 \q_stop { #1 . #2 }
+\cs_new_nopar:cpn { fp_use_large_aux_2:w } #1#2#3 \q_stop {
+ #1#2 . #3
+}
+\cs_new_nopar:cpn { fp_use_large_aux_3:w } #1#2#3#4 \q_stop {
+ #1#2#3 . #4
+}
+\cs_new_nopar:cpn { fp_use_large_aux_4:w } #1#2#3#4#5 \q_stop {
+ #1#2#3#4 . #5
+}
+\cs_new_nopar:cpn { fp_use_large_aux_5:w } #1#2#3#4#5#6 \q_stop {
+ #1#2#3#4#5 . #6
+}
+\cs_new_nopar:cpn { fp_use_large_aux_6:w } #1#2#3#4#5#6#7 \q_stop {
+ #1#2#3#4#5#6 . #7
+}
+\cs_new_nopar:cpn { fp_use_large_aux_7:w } #1#2#3#4#5#6#7#8 \q_stop {
+ #1#2#3#4#6#7 . #8
+}
+\cs_new_nopar:cpn { fp_use_large_aux_8:w } #1#2#3#4#5#6#7#8#9 \q_stop {
+ #1#2#3#4#5#6#7#8 . #9
+}
+\cs_new_nopar:cpn { fp_use_large_aux_9:w } #1 \q_stop { #1 . }
+\cs_new_nopar:Npn \fp_use_large_aux_ii:w #1 e #2 \q_stop {
+ #1
+ \prg_replicate:nn { #2 - 9 } { 0 }
+ .
+}
% \end{macrocode}
%\end{macro}
%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
%
-%\subsection{Internal utilities}
+%\subsection{Transferring to other types}
%
-%\begin{macro}{\fp_read:N}
-%\begin{macro}[aux]{\fp_read_aux:w}
-% Reading a stored value is made easier as the format is designed to
-% match the delimited function. This is always used to read the first
-% value (register "a").
+% The \cs{fp_use:N} function converts a floating point variable to
+% a form that can be used by \TeX. Here, the functions are slightly
+% different, as some information may be discarded.
+%
+%\begin{macro}{\fp_to_int:N}
+%\begin{macro}{\fp_to_int:c}
+%\begin{macro}[aux]{\fp_to_int_aux:w}
+%\begin{macro}[aux]{\fp_to_int_none:w}
+%\begin{macro}[aux]{\fp_to_int_small:w}
+%\begin{macro}[aux]{\fp_to_int_large:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_i:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_1:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_2:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_3:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_4:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_5:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_6:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_7:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_8:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux_i:w}
+%\begin{macro}[aux]{\fp_to_int_large_aux:nnn}
+%\begin{macro}[aux]{\fp_to_int_large_aux_ii:w}
+% Converting to integers in an expandable manner is very similar to
+% simply using floating point variables, particularly in the lead-off.
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \fp_read:N #1 {
- \exp_after:wN \fp_read_aux:w #1 \q_stop
+\cs_new_nopar:Npn \fp_to_int:N #1 {
+ \exp_after:wN \fp_to_int_aux:w #1 \q_stop
}
-\cs_new_protected_nopar:Npn \fp_read_aux:w #1#2 . #3 \q_stop {
+\cs_generate_variant:Nn \fp_to_int:N { c }
+\cs_new_nopar:Npn \fp_to_int_aux:w #1#2 e #3 \q_stop {
\tex_if:D #1 -
- \l_fp_input_a_sign_int \c_minus_one
+ -
+ \tex_fi:D
+ \tex_ifnum:D #3 < \c_zero
+ \exp_after:wN \fp_to_int_small:w
\tex_else:D
- \l_fp_input_a_sign_int \c_one
+ \exp_after:wN \fp_to_int_large:w
+ \tex_fi:D
+ #2 e #3 \q_stop
+}
+% \end{macrocode}
+% For small numbers, if the decimal part is greater than a half then
+% there is rounding up to do.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_int_small:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D #3 > \c_one
+ \tex_else:D
+ \tex_ifnum:D #1 < \c_five
+ 0
+ \tex_else:D
+ 1
+ \tex_fi:D
+ \tex_fi:D
+}
+% \end{macrocode}
+% For large numbers, the idea is to split off the part for rounding,
+% do the rounding and fill if needed.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_int_large:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D #3 < \c_ten
+ \exp_after:wN \fp_to_int_large_aux_i:w
+ \tex_else:D
+ \exp_after:wN \fp_to_int_large_aux_ii:w
\tex_fi:D
- \l_fp_input_a_integer_int #2 \scan_stop:
- \l_fp_input_a_decimal_int #3 \scan_stop:
+ #1#2 e #3 \q_stop
+}
+\cs_new_nopar:Npn \fp_to_int_large_aux_i:w #1#2 e #3 \q_stop {
+ \use:c { fp_to_int_large_aux_ #3 :w } #2 \q_stop {#1}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_1:w } #1#2 \q_stop {
+ \fp_to_int_large_aux:nnn { #2 0 } {#1}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_2:w } #1#2#3 \q_stop {
+ \fp_to_int_large_aux:nnn { #3 00 } {#1#2}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_3:w } #1#2#3#4 \q_stop {
+ \fp_to_int_large_aux:nnn { #4 000 } {#1#2#3}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_4:w } #1#2#3#4#5 \q_stop {
+ \fp_to_int_large_aux:nnn { #5 0000 } {#1#2#3#4}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_5:w } #1#2#3#4#5#6 \q_stop {
+ \fp_to_int_large_aux:nnn { #6 00000 } {#1#2#3#4#5}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_6:w } #1#2#3#4#5#6#7 \q_stop {
+ \fp_to_int_large_aux:nnn { #7 000000 } {#1#2#3#4#5#6}
+}
+\cs_new_nopar:cpn
+ { fp_to_int_large_aux_7:w } #1#2#3#4#5#6#7#8 \q_stop {
+ \fp_to_int_large_aux:nnn { #8 0000000 } {#1#2#3#4#5#6#7}
+}
+\cs_new_nopar:cpn
+ { fp_to_int_large_aux_8:w } #1#2#3#4#5#6#7#8#9 \q_stop {
+ \fp_to_int_large_aux:nnn { #9 00000000 } {#1#2#3#4#5#6#7#8}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_9:w } #1 \q_stop {#1}
+\cs_new_nopar:Npn \fp_to_int_large_aux:nnn #1#2#3 {
+ \tex_ifnum:D #1 < \c_five_hundred_million
+ #3#2
+ \tex_else:D
+ \tex_number:D \etex_numexpr:D #3#2 + 1 \scan_stop:
+ \tex_fi:D
+}
+\cs_new_nopar:Npn \fp_to_int_large_aux_ii:w #1 e #2 \q_stop {
+ #1
+ \prg_replicate:nn { #2 - 9 } { 0 }
}
% \end{macrocode}
%\end{macro}
%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
%
-%\begin{macro}{\fp_split:Nn}
-%\begin{macro}[aux]{\fp_split_sign:}
-%\begin{macro}[aux]{\fp_split_aux_i:w}
-%\begin{macro}[aux]{\fp_split_aux_ii:w}
-%\begin{macro}[aux]{\fp_split_aux_iii:w}
-%\begin{macro}[aux]{\fp_split_decimal:w}
-%\begin{macro}[aux]{\fp_split_decimal_aux:w}
-% The aim here is to use as much of \TeX's mechanism as possible to pick
-% up the numerical input without any mistakes. In particular, negative
-% numbers have to be filtered out first in case the integer part is
-% \( 0 \) (in which case \TeX\ would drop the "-" sign). That process
-% has to be done in a loop for cases where the sign is repeated. The
-% next phase is to find the integer part, which will terminate
-% with a ".", and trigger the decimal-finding code. The later will
-% allow the decimal to be too long, truncating the result.
+%\begin{macro}{\fp_to_tl:N}
+%\begin{macro}{\fp_to_tl:c}
+%\begin{macro}[aux]{\fp_to_tl_aux:w}
+%\begin{macro}[aux]{\fp_to_tl_large:w}
+%\begin{macro}[aux]{\fp_to_tl_large_aux_i:w}
+%\begin{macro}[aux]{\fp_to_tl_large_aux_ii:w}
+%\begin{macro}[aux]{\fp_to_tl_large_0:w}
+%\begin{macro}[aux]{\fp_to_tl_large_1:w}
+%\begin{macro}[aux]{\fp_to_tl_large_2:w}
+%\begin{macro}[aux]{\fp_to_tl_large_3:w}
+%\begin{macro}[aux]{\fp_to_tl_large_4:w}
+%\begin{macro}[aux]{\fp_to_tl_large_5:w}
+%\begin{macro}[aux]{\fp_to_tl_large_6:w}
+%\begin{macro}[aux]{\fp_to_tl_large_7:w}
+%\begin{macro}[aux]{\fp_to_tl_large_8:w}
+%\begin{macro}[aux]{\fp_to_tl_large_8_aux:w}
+%\begin{macro}[aux]{\fp_to_tl_large_9:w}
+%\begin{macro}[aux]{\fp_to_tl_small:w}
+%\begin{macro}[aux]{\fp_to_tl_small_one:w}
+%\begin{macro}[aux]{\fp_to_tl_small_two:w}
+%\begin{macro}[aux]{\fp_to_tl_small_aux:w}
+%\begin{macro}[aux]{\fp_to_tl_large_zeros:NNNNNNNNN}
+%\begin{macro}[aux]{\fp_to_tl_small_zeros:NNNNNNNNN}
+%\begin{macro}[aux]{\fp_use_iix_ix:NNNNNNNNN}
+%\begin{macro}[aux]{\fp_use_ix:NNNNNNNNN}
+%\begin{macro}[aux]{\fp_use_i_to_vii:NNNNNNNNN}
+%\begin{macro}[aux]{\fp_use_i_to_iix:NNNNNNNNN}
+% Converting to integers in an expandable manner is very similar to
+% simply using floating point variables, particularly in the lead-off.
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \fp_split:Nn #1#2 {
- \tl_set:Nx \l_fp_tmp_tl {#2}
- \l_fp_split_sign_int \c_one
- \fp_split_sign:
- \use:c { l_fp_input_ #1 _sign_int } \l_fp_split_sign_int
- \tex_afterassignment:D \fp_split_aux_i:w
- \use:c { l_fp_input_ #1 _integer_int }
- \etex_numexpr:D 0 \l_fp_tmp_tl . . \q_stop #1
+\cs_new_nopar:Npn \fp_to_tl:N #1 {
+ \exp_after:wN \fp_to_tl_aux:w #1 \q_stop
}
-\cs_new_protected_nopar:Npn \fp_split_sign: {
- \tex_ifnum:D \pdf_strcmp:D
- { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { - }
- = \c_zero
- \tl_set:Nx \l_fp_tmp_tl
- {
- \exp_after:wN
- \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
- }
- \l_fp_split_sign_int -\l_fp_split_sign_int
- \exp_after:wN \fp_split_sign:
- \tex_else:D
- \tex_ifnum:D \pdf_strcmp:D
- { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { + }
- = \c_zero
- \tl_set:Nx \l_fp_tmp_tl
- {
- \exp_after:wN
- \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
- }
+\cs_generate_variant:Nn \fp_to_tl:N { c }
+\cs_new_nopar:Npn \fp_to_tl_aux:w #1#2 e #3 \q_stop {
+ \tex_if:D #1 -
+ -
+ \tex_fi:D
+ \tex_ifnum:D #3 < \c_zero
+ \exp_after:wN \fp_to_tl_small:w
+ \tex_else:D
+ \exp_after:wN \fp_to_tl_large:w
+ \tex_fi:D
+ #2 e #3 \q_stop
+}
+% \end{macrocode}
+% For `large' numbers (exponent \( \ge 0 \)) there are two
+% cases. For very large exponents (\( \ge 10 \)) life is easy: apart
+% from dropping extra zeros there is no work to do. On the other hand,
+% for intermediate exponent values the decimal needs to be moved, then
+% zeros can be dropped.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_tl_large:w #1 e #2 \q_stop {
+ \tex_ifnum:D #2 < \c_ten
+ \exp_after:wN \fp_to_tl_large_aux_i:w
+ \tex_else:D
+ \exp_after:wN \fp_to_tl_large_aux_ii:w
+ \tex_fi:D
+ #1 e #2 \q_stop
+}
+\cs_new_nopar:Npn \fp_to_tl_large_aux_i:w #1 e #2 \q_stop {
+ \use:c { fp_to_tl_large_ #2 :w } #1 \q_stop
+}
+\cs_new_nopar:Npn \fp_to_tl_large_aux_ii:w #1 . #2 e #3 \q_stop {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ e #3
+}
+\cs_new_nopar:cpn { fp_to_tl_large_0:w } #1 . #2 \q_stop {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+}
+\cs_new_nopar:cpn { fp_to_tl_large_1:w } #1 . #2#3 \q_stop {
+ #1#2
+ \fp_to_tl_large_zeros:NNNNNNNNN #3 0
+}
+\cs_new_nopar:cpn { fp_to_tl_large_2:w } #1 . #2#3#4 \q_stop {
+ #1#2#3
+ \fp_to_tl_large_zeros:NNNNNNNNN #4 00
+}
+\cs_new_nopar:cpn { fp_to_tl_large_3:w } #1 . #2#3#4#5 \q_stop {
+ #1#2#3#4
+ \fp_to_tl_large_zeros:NNNNNNNNN #5 000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_4:w } #1 . #2#3#4#5#6 \q_stop {
+ #1#2#3#4#5
+ \fp_to_tl_large_zeros:NNNNNNNNN #6 0000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_5:w } #1 . #2#3#4#5#6#7 \q_stop {
+ #1#2#3#4#5#6
+ \fp_to_tl_large_zeros:NNNNNNNNN #7 00000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_6:w } #1 . #2#3#4#5#6#7#8 \q_stop {
+ #1#2#3#4#5#6#7
+ \fp_to_tl_large_zeros:NNNNNNNNN #8 000000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_7:w } #1 . #2#3#4#5#6#7#8#9 \q_stop {
+ #1#2#3#4#5#6#7#8
+ \fp_to_tl_large_zeros:NNNNNNNNN #9 0000000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_8:w } #1 . {
+ #1
+ \use:c { fp_to_tl_large_8_aux:w }
+}
+\cs_new_nopar:cpn
+ { fp_to_tl_large_8_aux:w } #1#2#3#4#5#6#7#8#9 \q_stop {
+ #1#2#3#4#5#6#7#8
+ \fp_to_tl_large_zeros:NNNNNNNNN #9 00000000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_9:w } #1 . #2 \q_stop {#1#2}
+% \end{macrocode}
+% Dealing with small numbers is a bit more complex as there has to be
+% rounding. This makes life rather awkward, as there need to be a series
+% of tests and calculations, as things cannot be stored in an
+% expandable system.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_tl_small:w #1 e #2 \q_stop {
+ \tex_ifnum:D #2 = \c_minus_one
+ \exp_after:wN \fp_to_tl_small_one:w
+ \tex_else:D
+ \tex_ifnum:D #2 = -\c_two
\exp_after:wN \exp_after:wN \exp_after:wN
- \fp_split_sign:
- \tex_fi:D
- \tex_fi:D
+ \fp_to_tl_small_two:w
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_to_tl_small_aux:w
+ \tex_fi:D
+ \tex_fi:D
+ #1 e #2 \q_stop
}
-\cs_new_protected_nopar:Npn \fp_split_aux_i:w #1 . #2 . #3 \q_stop {
- \fp_split_aux_ii:w #2 000000000 \q_stop
+\cs_new_nopar:Npn \fp_to_tl_small_one:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D \fp_use_ix:NNNNNNNNN #2 > \c_four
+ \tex_ifnum:D
+ \etex_numexpr:D #1 \fp_use_i_to_iix:NNNNNNNNN #2 + 1
+ < \c_one_thousand_million
+ 0.
+ \exp_after:wN \fp_to_tl_small_zeros:NNNNNNNNN
+ \tex_number:D
+ \etex_numexpr:D
+ #1 \fp_use_i_to_iix:NNNNNNNNN #2 + 1
+ \scan_stop:
+ \tex_else:D
+ 1
+ \tex_fi:D
+ \tex_else:D
+ 0. #1
+ \fp_to_tl_small_zeros:NNNNNNNNN #2
+ \tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_split_aux_ii:w #1#2#3#4#5#6#7#8#9 {
- \fp_split_aux_iii:w {#1#2#3#4#5#6#7#8#9}
+\cs_new_nopar:Npn \fp_to_tl_small_two:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D \fp_use_iix_ix:NNNNNNNNN #2 > \c_forty_four
+ \tex_ifnum:D
+ \etex_numexpr:D #1 \fp_use_i_to_vii:NNNNNNNNN #2 0 + \c_ten
+ < \c_one_thousand_million
+ 0.0
+ \exp_after:wN \fp_to_tl_small_zeros:NNNNNNNNN
+ \tex_number:D
+ \etex_numexpr:D
+ #1 \fp_use_i_to_vii:NNNNNNNNN #2 0 + \c_ten
+ \scan_stop:
+ \tex_else:D
+ 0.1
+ \tex_fi:D
+ \tex_else:D
+ 0.0
+ #1
+ \fp_to_tl_small_zeros:NNNNNNNNN #2
+ \tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_split_aux_iii:w #1#2 \q_stop {
- \l_fp_tmp_int 1 #1 \scan_stop:
- \exp_after:wN \fp_split_decimal:w
- \int_use:N \l_fp_tmp_int 000000000 \q_stop
+\cs_new_nopar:Npn \fp_to_tl_small_aux:w #1 . #2 e #3 \q_stop {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ e #3
}
-\cs_new_protected_nopar:Npn \fp_split_decimal:w #1#2#3#4#5#6#7#8#9 {
- \fp_split_decimal_aux:w {#2#3#4#5#6#7#8#9}
+% \end{macrocode}
+% Rather than a complex recursion, the tests for finding trailing zeros
+% are written out long-hand. The difference between the two is only the
+% need for a decimal marker.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_tl_large_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \tex_ifnum:D #9 = \c_zero
+ \tex_ifnum:D #8 = \c_zero
+ \tex_ifnum:D #7 = \c_zero
+ \tex_ifnum:D #6 = \c_zero
+ \tex_ifnum:D #5 = \c_zero
+ \tex_ifnum:D #4 = \c_zero
+ \tex_ifnum:D #3 = \c_zero
+ \tex_ifnum:D #2 = \c_zero
+ \tex_ifnum:D #1 = \c_zero
+ \tex_else:D
+ . #1
+ \tex_fi:D
+ \tex_else:D
+ . #1#2
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5#6
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5#6#7
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5#6#7#8
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5#6#7#8#9
+ \tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_split_decimal_aux:w #1#2#3 \q_stop #4 {
- \use:c { l_fp_input_ #4 _decimal_int } #1#2 \scan_stop:
- \tex_ifnum:D
- \etex_numexpr:D
- \use:c { l_fp_input_ #4 _integer_int } +
- \use:c { l_fp_input_ #4 _decimal_int }
- \scan_stop:
- = \c_zero
- \use:c { l_fp_input_ #4 _sign_int } \c_one
- \tex_fi:D
+\cs_new_nopar:Npn \fp_to_tl_small_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \tex_ifnum:D #9 = \c_zero
+ \tex_ifnum:D #8 = \c_zero
+ \tex_ifnum:D #7 = \c_zero
+ \tex_ifnum:D #6 = \c_zero
+ \tex_ifnum:D #5 = \c_zero
+ \tex_ifnum:D #4 = \c_zero
+ \tex_ifnum:D #3 = \c_zero
+ \tex_ifnum:D #2 = \c_zero
+ \tex_ifnum:D #1 = \c_zero
+ \tex_else:D
+ #1
+ \tex_fi:D
+ \tex_else:D
+ #1#2
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5#6
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5#6#7
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5#6#7#8
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5#6#7#8#9
+ \tex_fi:D
}
% \end{macrocode}
+% Some quick `return a few' functions.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use_iix_ix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {#8#9}
+\cs_new_nopar:Npn \fp_use_ix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {#9}
+\cs_new_nopar:Npn \fp_use_i_to_vii:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ #1#2#3#4#5#6#7
+}
+\cs_new_nopar:Npn \fp_use_i_to_iix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ #1#2#3#4#5#6#7#8
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
@@ -1233,6 +2042,174 @@
%\end{macro}
%\end{macro}
%
+%\subsection{Rounding numbers}
+%
+% The results may well need to be rounded. A couple of related functions
+% to do this for a stored value.
+%
+%\begin{macro}{\fp_round_figures:Nn}
+%\begin{macro}{\fp_round_figures:cn}
+%\begin{macro}{\fp_ground_figures:Nn}
+%\begin{macro}{\fp_ground_figures:cn}
+%\begin{macro}[aux]{\fp_round_figures_aux:NNn}
+% Rounding to figures needs only an adjustment to the target by one
+% (as the target is in decimal places).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_round_figures:Nn {
+ \fp_round_figures_aux:NNn \tl_set:Nn
+}
+\cs_generate_variant:Nn \fp_round_figures:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ground_figures:Nn {
+ \fp_round_figures_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_ground_figures:Nn { c }
+\cs_new_protected_nopar:Npn \fp_round_figures_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_read:N #2
+ \int_set:Nn \l_fp_round_target_int { #3 - 1 }
+ \tex_ifnum:D \l_fp_round_target_int < \c_ten
+ \exp_after:wN \fp_round:
+ \tex_fi:D
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_round_places:Nn}
+%\begin{macro}{\fp_round_places:cn}
+%\begin{macro}{\fp_ground_places:Nn}
+%\begin{macro}{\fp_ground_places:cn}
+%\begin{macro}[aux]{\fp_round_places_aux:NNn}
+% Rounding to places needs an adjustment for the exponent value, which
+% will mean that everything should be correct.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_round_places:Nn {
+ \fp_round_places_aux:NNn \tl_set:Nn
+}
+\cs_generate_variant:Nn \fp_round_places:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ground_places:Nn {
+ \fp_round_places_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_ground_places:Nn { c }
+\cs_new_protected_nopar:Npn \fp_round_places_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_read:N #2
+ \int_set:Nn \l_fp_round_target_int
+ { #3 + \l_fp_input_a_exponent_int }
+ \tex_ifnum:D \l_fp_round_target_int < \c_ten
+ \exp_after:wN \fp_round:
+ \tex_fi:D
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_round:}
+%\begin{macro}{\fp_round_aux:NNNNNNNNN}
+%\begin{macro}{\fp_round_loop:N}
+% The rounding approach is the same for decimal places and significant
+% figures. There are always nine decimal digits to round, so the code
+% can be written to account for this. The basic logic is simply to
+% find the rounding, track any carry digit and move along. At the end
+% of the loop there is a possible shuffle if the integer part has
+% become \( 10 \).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_round: {
+ \bool_set_false:N \l_fp_round_carry_bool
+ \l_fp_round_position_int \c_eight
+ \tl_clear:N \l_fp_round_decimal_tl
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_round_aux:NNNNNNNNN \int_use:N \l_fp_input_a_decimal_int
+}
+\cs_new_protected_nopar:Npn \fp_round_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \fp_round_loop:N #9#8#7#6#5#4#3#2#1
+ \bool_if:NT \l_fp_round_carry_bool
+ { \tex_advance:D \l_fp_input_a_integer_int \c_one }
+ \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
+ \tex_ifnum:D \l_fp_input_a_integer_int < \c_ten
+ \tex_else:D
+ \l_fp_input_a_integer_int \c_one
+ \tex_divide:D \l_fp_input_a_decimal_int \c_ten
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_round_loop:N #1 {
+ \tex_ifnum:D \l_fp_round_position_int < \l_fp_round_target_int
+ \bool_if:NTF \l_fp_round_carry_bool
+ { \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop: }
+ { \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop: }
+ \tex_ifnum:D \l_fp_tmp_int = \c_ten
+ \l_fp_tmp_int \c_zero
+ \tex_else:D
+ \bool_set_false:N \l_fp_round_carry_bool
+ \tex_fi:D
+ \tl_set:Nx \l_fp_round_decimal_tl
+ { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
+ \tex_else:D
+ \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
+ \tex_ifnum:D \l_fp_round_position_int = \l_fp_round_target_int
+ \tex_ifnum:D #1 > \c_four
+ \bool_set_true:N \l_fp_round_carry_bool
+ \tex_fi:D
+ \tex_fi:D
+ \tex_fi:D
+ \tex_advance:D \l_fp_round_position_int \c_minus_one
+ \tex_ifnum:D \l_fp_round_position_int > \c_minus_one
+ \exp_after:wN \fp_round_loop:N
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
%\subsection{Unary functions}
%
%\begin{macro}{\fp_abs:N}
@@ -1244,27 +2221,32 @@
% return the result.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_abs:N {
- \fp_abs:NN \tl_set:Nn
+ \fp_abs_aux:NN \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gabs:N {
- \fp_abs:NN \tl_gset:Nn
+ \fp_abs_aux:NN \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_abs:N { c }
\cs_generate_variant:Nn \fp_gabs:N { c }
-\cs_new_protected_nopar:Npn \fp_abs:NN #1#2 {
+\cs_new_protected_nopar:Npn \fp_abs_aux:NN #1#2 {
\group_begin:
\fp_read:N #2
\tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
+ \cs_set_protected_nopar:Npx \fp_tmp:w
{
- +
- \int_use:N \l_fp_input_a_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_input_a_decimal_int
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ +
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
}
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w
}
% \end{macrocode}
%\end{macro}
@@ -1304,6 +2286,8 @@
.
\exp_after:wN \use_none:n
\int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
}
\exp_after:wN \group_end: \exp_after:wN
#1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
@@ -1323,6 +2307,8 @@
%\begin{macro}{\fp_gadd:cn}
%\begin{macro}[aux]{\fp_add_aux:NNn}
%\begin{macro}[aux]{\fp_add_core:}
+%\begin{macro}[aux]{\fp_add_sum:}
+%\begin{macro}[aux]{\fp_add_difference:}
% The various addition functions are simply different ways to call the
% single master function below. This pattern is repeated for the
% other arithmetic functions.
@@ -1345,11 +2331,16 @@
\group_begin:
\fp_read:N #2
\fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
\fp_add_core:
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w #1#2
}
-\cs_new_protected_nopar:Npn \fp_add_core: {
+\cs_new_protected_nopar:Npn \fp_add_core: {
+ \fp_level_input_exponents:
\tex_ifnum:D
\etex_numexpr:D
\l_fp_input_a_sign_int * \l_fp_input_b_sign_int
@@ -1358,18 +2349,31 @@
\exp_after:wN \fp_add_sum:
\tex_else:D
\exp_after:wN \fp_add_difference:
- \tex_fi:D
- \tl_set:Nx \l_fp_tmp_tl
+ \tex_fi:D
+ \l_fp_output_exponent_int \l_fp_input_a_exponent_int
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
{
- \tex_ifnum:D \l_fp_output_sign_int < \c_zero
- -
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_output_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_output_decimal_int
+ \group_end:
+ ##1 ##2
+ {
+ \tex_ifnum:D \l_fp_output_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
}
}
% \end{macrocode}
@@ -1386,16 +2390,16 @@
\l_fp_input_a_decimal_int + \l_fp_input_b_decimal_int
\scan_stop:
\tex_ifnum:D \l_fp_output_decimal_int < \c_one_thousand_million
- \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
\tex_else:D
\tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int -\c_one_thousand_million
\tex_fi:D
}
% \end{macrocode}
% When the signs of the two parts of the input are different, the
-% absolute difference is worked out first. There is then a caculation to
-% see which way around everything has worked out, so that the final
-% sign is correct. The differnce might also give a zero resul with
+% absolute difference is worked out first. There is then a calculation
+% to see which way around everything has worked out, so that the final
+% sign is correct. The difference might also give a zero result with
% a negative sign, which is reversed as zero is regarded as positive.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_add_difference: {
@@ -1427,15 +2431,7 @@
\tex_fi:D
\tex_else:D
\l_fp_output_sign_int \l_fp_input_a_sign_int
- \tex_fi:D
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_output_integer_int + \l_fp_output_decimal_int
- \scan_stop:
- = \c_zero
- \l_fp_output_sign_int \c_one
- \tex_fi:D
- \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \tex_fi:D
}
% \end{macrocode}
%\end{macro}
@@ -1444,6 +2440,8 @@
%\end{macro}
%\end{macro}
%\end{macro}
+%\end{macro}
+%\end{macro}
%
%\begin{macro}{\fp_sub:Nn}
%\begin{macro}{\fp_sub:cn}
@@ -1466,27 +2464,32 @@
\group_begin:
\fp_read:N #2
\fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
\tex_multiply:D \l_fp_input_b_sign_int \c_minus_one
\fp_add_core:
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w #1#2
}
% \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
-%\end{macro}
+%\end{macro}
%
%\begin{macro}{\fp_mul:Nn}
%\begin{macro}{\fp_mul:cn}
%\begin{macro}{\fp_gmul:Nn}
%\begin{macro}{\fp_gmul:cn}
%\begin{macro}[aux]{\fp_mul_aux:NNn}
+%\begin{macro}[aux]{\fp_mul_int:}
%\begin{macro}[aux]{\fp_mul_split:NNNN}
%\begin{macro}[aux]{\fp_mul_split:w}
%\begin{macro}[aux]{\fp_mul_end_level:}
-%\begin{macro}[aux]{\fp_mul_end_level:w}
+%\begin{macro}[aux]{\fp_mul_end_level:NNNNNNNNN}
% The pattern is much the same for multiplication.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_mul:Nn {
@@ -1509,93 +2512,83 @@
\group_begin:
\fp_read:N #2
\fp_split:Nn b {#3}
- \fp_mul_split:NNNN \l_fp_input_a_integer_int
- \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
- \fp_mul_split:NNNN \l_fp_input_a_decimal_int
- \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
- \fp_mul_split:NNNN \l_fp_input_b_integer_int
- \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
- \fp_mul_split:NNNN \l_fp_input_b_decimal_int
- \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
- \l_fp_mul_output_int \c_zero
- \tl_clear:N \l_fp_mul_output_tl
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_vi_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_iv_int
- \tex_divide:D \l_fp_mul_output_int \c_thousand
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_vi_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_iii_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_vi_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_ii_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_vi_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \l_fp_output_decimal_int 0 \l_fp_mul_output_tl \scan_stop:
- \tl_clear:N \l_fp_mul_output_tl
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \l_fp_output_integer_int 0 \l_fp_mul_output_tl \scan_stop:
- \tl_clear:N \l_fp_mul_output_tl
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \tex_ifnum:D \l_fp_mul_output_tl = \c_zero
- \tex_else:D
- \exp_after:wN \fp_msg_overflow:
- \tex_fi:D
- \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_mul_int:
+ \l_fp_output_exponent_int
+ \etex_numexpr:D
+ \l_fp_input_a_exponent_int + \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w
{
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
- \scan_stop:
- < \c_zero
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_output_integer_int + \l_fp_output_decimal_int
- \scan_stop:
- = \c_one_thousand_million
- +
- \tex_else:D
- -
- \tex_fi:D
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_output_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_output_decimal_int
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ < \c_zero
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_output_integer_int + \l_fp_output_decimal_int
+ = \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
}
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w
+}
+% \end{macrocode}
+% Done separately so that the internal use is a bit easier.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul_int: {
+ \fp_mul_split:NNNN \l_fp_input_a_decimal_int
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN \l_fp_input_b_decimal_int
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \l_fp_output_decimal_int 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \l_fp_output_integer_int 0 \l_fp_mul_output_tl \scan_stop:
}
% \end{macrocode}
% The split works by making a \( 10 \) digit number, from which
@@ -1613,6 +2606,7 @@
#4 ##8##9 \scan_stop:
}
\exp_after:wN \fp_mul_split_aux:w \int_use:N #1 \q_stop
+ \tex_advance:D #1 -\c_one_thousand_million
}
\cs_new_protected_nopar:Npn \fp_mul_product:NN #1#2 {
\l_fp_mul_output_int
@@ -1625,18 +2619,19 @@
% \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_mul_end_level: {
\tex_advance:D \l_fp_mul_output_int \c_one_thousand_million
- \exp_after:wN \fp_mul_end_level:w
- \int_use:N \l_fp_mul_output_int \q_stop
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_mul_end_level:NNNNNNNNN \int_use:N \l_fp_mul_output_int
}
-\cs_new_protected_nopar:Npn \fp_mul_end_level:w
- #1#2#3#4#5#6#7#8#9 \q_stop {
- \tl_set:Nx \l_fp_mul_output_tl { #8#9 \l_fp_mul_output_tl }
- \l_fp_mul_output_int #5#6#7 \scan_stop:
+\cs_new_protected_nopar:Npn \fp_mul_end_level:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9 {
+ \tl_set:Nx \l_fp_mul_output_tl { #7#8#9 \l_fp_mul_output_tl }
+ \l_fp_mul_output_int #1#2#3#4#5#6 \scan_stop:
}
% \end{macrocode}
%\end{macro}
%\end{macro}
-%\end{macro}
+%\end{macro}
+%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
@@ -1650,11 +2645,7 @@
%\begin{macro}{\fp_gdiv:cn}
%\begin{macro}[aux]{\fp_div_aux:NNn}
%\begin{macro}[aux]{\fp_div_aux:}
-%\begin{macro}[aux]{\fp_div_offset_create:}
-%\begin{macro}[aux]{\fp_div_offset_create_aux:w}
%\begin{macro}[aux]{\fp_div_loop:}
-%\begin{macro}[aux]{\fp_div_loop_aux_i:w}
-%\begin{macro}[aux]{\fp_div_loop_aux_ii:w}
%\begin{macro}[aux]{\fp_div_divide:}
%\begin{macro}[aux]{\fp_div_divide_aux:}
%\begin{macro}[aux]{\fp_div_store:}
@@ -1681,120 +2672,113 @@
\group_begin:
\fp_read:N #2
\fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
\tex_ifnum:D
\etex_numexpr:D
\l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
- \scan_stop:
= \c_zero
- \tl_set_eq:NN \l_fp_tmp_tl \c_undefined_fp
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \c_undefined_fp }
+ }
\tex_else:D
\tex_ifnum:D
\etex_numexpr:D
\l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
- \scan_stop:
= \c_zero
- \tl_set_eq:NN \l_fp_tmp_tl \c_zero_fp
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \c_zero_fp }
+ }
\tex_else:D
\exp_after:wN \exp_after:wN \exp_after:wN
\fp_div_aux:
\tex_fi:D
\tex_fi:D
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
-}
-% \end{macrocode}
-% The main division algorithm has to avoid overflows for awkward
-% cases (division of large numbers by small ones). That requires that
-% the denominator has an integer part if the numerator does: an offset
-% is only created if it is needed. The idea then is find how many
-% times the denominator can be removed from the numerator. This
-% is stored in the result, the denominator is divided by ten and
-% the process is repeated with the remainder of the numerator. Cycling
-% through this sequence eventually removes all of the digits of the
-% denominator, if the numerator does not reach zero first.
+ \fp_tmp:w #1#2
+}
+% \end{macrocode}
+% The main division algorithm works by finding how many times "b" can
+% be removed from "a", storing the result and doing the subtraction.
+% Input "a" is then multiplied by \( 10 \), and the process is repeated.
+% The looping ends either when there is nothing left of "a"
+% (\emph{i.e.}~an exact result) or when the code reaches the ninth
+% decimal place. Most of the process takes place in the loop function
+% below.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_div_aux: {
- \l_fp_div_offset_int \c_one
- \tex_ifnum:D \l_fp_input_a_integer_int > \c_zero
- \exp_after:wN \fp_div_offset_create:
- \tex_fi:D
\l_fp_output_integer_int \c_zero
- \l_fp_output_decimal_int \c_one_thousand_million
+ \l_fp_output_decimal_int \c_zero
\cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
+ \l_fp_div_offset_int \c_one_hundred_million
\fp_div_loop:
- \tl_set:Nx \l_fp_tmp_tl
+ \l_fp_output_exponent_int
+ \etex_numexpr:D
+ \l_fp_input_a_exponent_int - \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
{
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
- \scan_stop:
- < \c_zero
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_output_integer_int + \l_fp_output_decimal_int
- \scan_stop:
- = \c_one_thousand_million
- +
- \tex_else:D
- -
- \tex_fi:D
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_output_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_output_decimal_int
+ \group_end:
+ ##1 ##2
+ {
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ < \c_zero
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_output_integer_int + \l_fp_output_decimal_int
+ = \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
}
}
% \end{macrocode}
-% The offset is created such that it will automatically be accounted
-% for in the rest of the process. Rather than doing any integer division
-% a delimited function is used to transfer the digit from the
-% integer to the decimal parts.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \fp_div_offset_create: {
- \tex_ifnum:D \l_fp_input_b_integer_int = \c_zero
- \tex_advance:D \l_fp_input_b_decimal_int \c_one_thousand_million
- \exp_after:wN \fp_div_offset_create_aux:w
- \int_use:N \l_fp_input_b_decimal_int \q_stop
- \exp_after:wN \fp_div_offset_create:
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_div_offset_create_aux:w
- #1#2#3#4#5#6#7#8#9 \q_stop {
- \l_fp_input_b_integer_int #2 \scan_stop:
- \l_fp_input_b_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
- \tex_multiply:D \l_fp_div_offset_int \c_ten
-}
-% \end{macrocode}
-% The main division loop must start with both numerator and
-% denominator above zero, so the test is at the tail of the loop.
-% Once again, division by ten for the denominator is avoided, with
-% a delimited function doing the job. The test at the end of the
-% function means that the loop terminates as soon as one part of the
-% input reaches zero: this saves dead loops if the division is
-% exact.
+% The main loop implements the approach described above. The storing
+% function is done as a function so that the integer and decimal parts
+% can be done separately but rapidly.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_div_loop: {
- \l_fp_div_count_int \c_zero
+ \l_fp_count_int \c_zero
\fp_div_divide:
- \tex_divide:D \l_fp_input_b_decimal_int \c_ten
- \tex_advance:D \l_fp_input_b_integer_int \c_one_thousand_million
- \exp_after:wN \fp_div_loop_aux_i:w
- \int_use:N \l_fp_input_b_integer_int
\fp_div_store:
+ \tex_multiply:D \l_fp_input_a_integer_int \c_ten
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \fp_div_loop_step:w
+ \int_use:N \l_fp_input_a_decimal_int \q_stop
\tex_ifnum:D
\etex_numexpr:D
\l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
> \c_zero
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
- > \c_zero
- \exp_after:wN \exp_after:wN \exp_after:wN
- \fp_div_loop:
- \tex_fi:D
+ \tex_ifnum:D \l_fp_div_offset_int > \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_div_loop:
+ \tex_fi:D
\tex_fi:D
}
% \end{macrocode}
@@ -1820,18 +2804,8 @@
\tex_fi:D
\tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_div_loop_aux_i:w #1#2#3#4#5#6#7#8#9 {
- \fp_div_loop_aux_ii:w #2#3#4#5#6#7#8#9
-}
-\cs_new_protected_nopar:Npn \fp_div_loop_aux_ii:w #1#2#3#4#5#6#7#8#9 {
- \l_fp_input_b_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
- \l_fp_input_b_decimal_int
- \etex_numexpr:D
- \l_fp_input_b_decimal_int + \c_one_hundred_million * #9
- \scan_stop:
-}
\cs_new_protected_nopar:Npn \fp_div_divide_aux: {
- \tex_advance:D \l_fp_div_count_int \c_one
+ \tex_advance:D \l_fp_count_int \c_one
\tex_advance:D \l_fp_input_a_integer_int -\l_fp_input_b_integer_int
\tex_advance:D \l_fp_input_a_decimal_int -\l_fp_input_b_decimal_int
\tex_ifnum:D \l_fp_input_a_decimal_int < \c_zero
@@ -1841,52 +2815,964 @@
\fp_div_divide:
}
% \end{macrocode}
-% The final stage of each loop is to store the result. This is done
-% separately for the integer and decimal parts. The offset is used to
-% get the digits in the correct place, and so also indicates when the
-% switch from the integer to the decimal.
+% Storing the number of each division is done differently for the
+% integer and decimal. The integer is easy and a one-off, while the
+% decimal also needs to account for the position of the digit to store.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_div_store: { }
\cs_new_protected_nopar:Npn \fp_div_store_integer: {
- \l_fp_output_integer_int
- \etex_numexpr:D
- \l_fp_output_integer_int +
- \l_fp_div_count_int * \l_fp_div_offset_int
- \scan_stop:
- \tex_ifnum:D \l_fp_div_offset_int > \c_one
- \tex_divide:D \l_fp_div_offset_int \c_ten
- \tex_else:D
- \cs_set_eq:NN \fp_div_store: \fp_div_store_decimal:
- \l_fp_div_offset_int \c_one_hundred_million
- \tex_fi:D
+ \l_fp_output_integer_int \l_fp_count_int
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_decimal:
}
\cs_new_protected_nopar:Npn \fp_div_store_decimal: {
\l_fp_output_decimal_int
\etex_numexpr:D
\l_fp_output_decimal_int +
- \l_fp_div_count_int * \l_fp_div_offset_int
+ \l_fp_count_int * \l_fp_div_offset_int
\scan_stop:
\tex_divide:D \l_fp_div_offset_int \c_ten
}
+\cs_new_protected_nopar:Npn
+ \fp_div_loop_step:w #1#2#3#4#5#6#7#8#9 \q_stop {
+ \l_fp_input_a_integer_int
+ \etex_numexpr:D
+ #2 + \l_fp_input_a_integer_int
+ \scan_stop:
+ \l_fp_input_a_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
+}
% \end{macrocode}
%\end{macro}
+%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
+%\end{macro}
+%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
+%\end{macro}
+%
+%\subsection{Arithmetic for internal use}
+%
+% For the more complex functions, it is only possible to deliver
+% reliable \( 10 \) digit accuracy if the internal calculations are
+% carried out to a higher degree of precision. This is done using a
+% second set of functions so that the `user' versions are not
+% slowed down. These versions are also focussed on the needs of internal
+% calculations. No error checking, sign checking or exponent levelling
+% is done. For addition and subtraction, the arguments are:
+% \begin{itemize}
+% \item Integer part of input "a".
+% \item Decimal part of input "a".
+% \item Additional decimal part of input "a".
+% \item Integer part of input "b".
+% \item Decimal part of input "b".
+% \item Additional decimal part of input "b".
+% \item Integer part of output.
+% \item Decimal part of output.
+% \item Additional decimal part of output.
+% \end{itemize}
+% The situation for multiplication and division is a little different as
+% they only deal with the decimal part.
+%
+%\begin{macro}{\fp_add:NNNNNNNNN}
+% The internal sum is always exactly that: it is always a sum and there
+% is no sign check.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_add:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ #7 \etex_numexpr:D #1 + #4 \scan_stop:
+ #8 \etex_numexpr:D #2 + #5 \scan_stop:
+ #9 \etex_numexpr:D #3 + #6 \scan_stop:
+ \tex_ifnum:D #9 < \c_one_thousand_million
+ \tex_else:D
+ \tex_advance:D #8 \c_one
+ \tex_advance:D #9 -\c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D #8 < \c_one_thousand_million
+ \tex_else:D
+ \tex_advance:D #7 \c_one
+ \tex_advance:D #8 -\c_one_thousand_million
+ \tex_fi:D
+}
+% \end{macrocode}
%\end{macro}
+%
+%\begin{macro}{\fp_sub:NNNNNNNNNN}
+% Internal subtraction is needed only when the first number is bigger
+% than the second, so there is no need to worry about the sign. This is
+% a good job as there are no arguments left.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sub:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ #7 \etex_numexpr:D #1 - #4 \scan_stop:
+ #8 \etex_numexpr:D #2 - #5 \scan_stop:
+ #9 \etex_numexpr:D #3 - #6 \scan_stop:
+ \tex_ifnum:D #9 < \c_zero
+ \tex_advance:D #8 \c_minus_one
+ \tex_advance:D #9 \c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D #8 < \c_zero
+ \tex_advance:D #7 \c_minus_one
+ \tex_advance:D #8 \c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D #7 < \c_zero
+ \tex_ifnum:D \etex_numexpr:D #8 + #9 = \c_zero
+ #7 -#7
+ \tex_else:D
+ \tex_advance:D #7 \c_one
+ #8 \etex_numexpr:D \c_one_thousand_million - #8 \scan_stop:
+ #9 \etex_numexpr:D \c_one_thousand_million - #9 \scan_stop:
+ \tex_fi:D
+ \tex_fi:D
+}
+% \end{macrocode}
%\end{macro}
+%
+%\begin{macro}{\fp_mul:NNNNNN}
+% Decimal-part only multiplication but with higher accuracy than the
+% user version.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul:NNNNNN #1#2#3#4#5#6 {
+ \fp_mul_split:NNNN #1
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN #2
+ \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
+ \fp_mul_split:NNNN #3
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_split:NNNN #4
+ \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_vi_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_ii_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ #6 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_end_level:
+ #5 0 \l_fp_mul_output_tl \scan_stop:
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\fp_div_integer:NNNNN}
+% Here, division is always by an integer, and so it is possible to
+% use \TeX's native calculations rather than doing it in macros.
+% The idea here is to divide the decimal part, find any remainder,
+% then do the real division of the two parts before adding in what
+% is needed for the remainder.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_div_integer:NNNNN #1#2#3#4#5 {
+ \l_fp_tmp_int #1
+ \tex_divide:D \l_fp_tmp_int #3
+ \l_fp_tmp_int \etex_numexpr:D #1 - \l_fp_tmp_int * #3 \scan_stop:
+ #4 #1
+ \tex_divide:D #4 #3
+ #5 #2
+ \tex_divide:D #5 #3
+ \tex_multiply:D \l_fp_tmp_int \c_one_thousand
+ \tex_divide:D \l_fp_tmp_int #3
+ #5 \etex_numexpr:D #5 + \l_fp_tmp_int * \c_one_million \scan_stop:
+ \tex_ifnum:D #5 > \c_one_thousand_million
+ \tex_advance:D #4 \c_one
+ \tex_advancd:D #5 -\c_one_thousand_million
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\subsection{Trigonometric functions}
+%
+%\begin{macro}{\fp_trig_normalise:}
+%\begin{macro}[aux]{\fp_trig_normalise_aux_i:}
+%\begin{macro}[aux]{\fp_trig_normalise_aux:w}
+%\begin{macro}[aux]{\fp_trig_normalise_aux_ii:}
+%\begin{macro}[aux]{\fp_trig_normalise_aux:NNNNNNNNN}
+%\begin{macro}[aux]{\fp_trig_normalise_aux_iii:}
+% For normalisation, the code essentially switches to fixed-point
+% arithmetic. There is a shift of the exponent, then repeated
+% subtractions. The end result is a number in the range
+% \( -\pi < x \le \pi \).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_normalise: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int < \c_ten
+ \l_fp_input_a_extended_int \c_zero
+ \fp_trig_normalise_aux_i:
+ \fp_trig_normalise_aux_ii:
+ \fp_trig_normalise_aux_iii:
+ \tex_ifnum:D \l_fp_input_a_integer_int < \c_zero
+ \l_fp_input_a_sign_int -\l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int -\l_fp_input_a_integer_int
+ \tex_fi:D
+ \exp_after:wN \fp_trig_octant:
+ \tex_else:D
+ \l_fp_input_a_sign_int \c_one
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \exp_after:wN \fp_trig_overflow_msg:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_normalise_aux_i: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int > \c_zero
+ \tex_multiply:D \l_fp_input_a_integer_int \c_ten
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \fp_trig_normalise_aux:w
+ \int_use:N \l_fp_input_a_decimal_int \q_stop
+ \exp_after:wN \fp_trig_normalise_aux_i:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_trig_normalise_aux:w #1#2#3#4#5#6#7#8#9 \q_stop {
+ \l_fp_input_a_integer_int
+ \etex_numexpr:D \l_fp_input_a_integer_int + #2 \scan_stop:
+ \l_fp_input_a_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_minus_one
+}
+\cs_new_protected_nopar:Npn \fp_trig_normalise_aux_ii: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int < \c_zero
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_trig_normalise_aux:NNNNNNNNN
+ \int_use:N \l_fp_input_a_decimal_int
+ \exp_after:wN \fp_trig_normalise_aux_ii:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_trig_normalise_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \tex_ifnum:D \l_fp_input_a_integer_int = \c_zero
+ \l_fp_input_a_decimal_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_else:D
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_use:N \l_fp_input_a_integer_int
+ #1#2#3#4#5#6#7#8
+ }
+ \l_fp_input_a_integer_int \c_zero
+ \l_fp_input_a_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_fi:D
+ \tex_divide:D \l_fp_input_a_extended_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \int_use:N \l_fp_input_a_extended_int
+ }
+ \l_fp_input_a_extended_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+}
+\cs_new_protected_nopar:Npn \fp_trig_normalise_aux_iii: {
+ \tex_ifnum:D \l_fp_input_a_integer_int > \c_three
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_six \c_fp_two_pi_decimal_int \c_fp_two_pi_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \exp_after:wN \fp_trig_normalise_aux_iii:
+ \tex_else:D
+ \tex_ifnum:D \l_fp_input_a_integer_int > \c_two
+ \tex_ifnum:D \l_fp_input_a_decimal_int > \c_fp_pi_decimal_int
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_six \c_fp_two_pi_decimal_int \c_fp_two_pi_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_trig_normalise_aux_iii:
+ \tex_fi:D
+ \tex_fi:D
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_trig_octant:}
+%\begin{macro}[aux]{\fp_trig_octant_aux:}
+% Here, the input is further reduced into the range
+% \( 0 \le x < \pi / 4 \). This is pretty simple: check if
+% \( \pi / 4 \) can be taken off and if it can do it and loop. The
+% check at the end is to `mop up' values which are so close to
+% \( \pi / 4 \) that they should be treated as such. The test for
+% an even octant is needed as the `remainder' needed is from
+% the nearest \( \pi / 2 \).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_octant: {
+ \l_fp_trig_octant_int \c_one
+ \fp_trig_octant_aux:
+ \tex_ifnum:D \l_fp_input_a_decimal_int < \c_ten
+ \l_fp_input_a_decimal_int \c_zero
+ \l_fp_input_a_extended_int \c_zero
+ \tex_fi:D
+ \tex_ifodd:D \l_fp_trig_octant_int
+ \tex_else:D
+ \fp_sub:NNNNNNNNN
+ \c_zero \c_fp_pi_by_four_decimal_int \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_octant_aux: {
+ \tex_ifnum:D \l_fp_input_a_integer_int > \c_zero
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_zero \c_fp_pi_by_four_decimal_int \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_advance:D \l_fp_trig_octant_int \c_one
+ \exp_after:wN \fp_trig_octant_aux:
+ \tex_else:D
+ \tex_ifnum:D
+ \l_fp_input_a_decimal_int > \c_fp_pi_by_four_decimal_int
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_zero \c_fp_pi_by_four_decimal_int
+ \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_advance:D \l_fp_trig_octant_int \c_one
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_trig_octant_aux:
+ \tex_fi:D
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_sin:Nn}
+%\begin{macro}{\fp_sin:cn}
+%\begin{macro}{\fp_gsin:Nn}
+%\begin{macro}{\fp_gsin:cn}
+%\begin{macro}[aux]{\fp_sin_aux:NNn}
+%\begin{macro}[aux]{\fp_sin_aux_i:}
+%\begin{macro}[aux]{\fp_sin_aux_ii:}
+% Calculating the sine starts off in the usual way. There is a check
+% to see if the value has already been worked out before proceeding
+% further.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sin:Nn {
+ \fp_sin_aux:NNn \tl_set:Nn
+}
+\cs_new_protected_nopar:Npn \fp_gsin:Nn {
+ \fp_sin_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_sin:Nn { c }
+\cs_generate_variant:Nn \fp_gsin:Nn { c }
+% \end{macrocode}
+% The internal routine for sines does a check to see if the value is
+% already known. This saves a lot of repetition when doing rotations.
+% For very small values it is best to simply return the input as the
+% sine: the cut-off is \( 1 \times 10^{-5} \).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sin_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_trig_arg_tl
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \tex_ifnum:D \l_fp_input_a_exponent_int < -\c_five
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \l_fp_trig_arg_tl }
+ }
+ \tex_else:D
+ \etex_ifcsname:D
+ c_fp_sin ( \l_fp_trig_arg_tl ) _tl
+ \tex_endcsname:D
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_sin_aux_i:
+ \tex_fi:D
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_sin ( \l_fp_trig_arg_tl ) _tl } }
+ }
+ \tex_fi:D
+ \fp_tmp:w
+}
+% \end{macrocode}
+% The internals for sine first normalise the input into an octant, then
+% choose the correct set up for the Taylor series. The sign for the sine
+% function is easy, so there is no worry about it. So the only thing to
+% do is to get the output standardised.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sin_aux_i: {
+ \fp_trig_normalise:
+ \fp_sin_aux_ii:
+ \tex_ifnum:D \l_fp_output_integer_int = \c_one
+ \l_fp_output_exponent_int \c_zero
+ \tex_else:D
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_decimal_int \l_fp_output_extended_int
+ \l_fp_output_exponent_int -\c_nine
+ \tex_fi:D
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_sin ( \l_fp_trig_arg_tl ) _tl }
+ \tl_set:cx { c_fp_sin ( \l_fp_trig_arg_tl ) _tl }
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int > \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+}
+\cs_new_protected_nopar:Npn \fp_sin_aux_ii: {
+ \tex_ifcase:D \l_fp_trig_octant_int
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_sin:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_cos:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_cos:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_sin:
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_cos:Nn}
+%\begin{macro}{\fp_cos:cn}
+%\begin{macro}{\fp_gcos:Nn}
+%\begin{macro}{\fp_gcos:cn}
+%\begin{macro}[aux]{\fp_cos_aux:NNn}
+%\begin{macro}[aux]{\fp_cos_aux_i:}
+%\begin{macro}[aux]{\fp_cos_aux_ii:}
+% Cosine is almost identical, but there is no short cut code here.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_cos:Nn {
+ \fp_cos_aux:NNn \tl_set:Nn
+}
+\cs_new_protected_nopar:Npn \fp_gcos:Nn {
+ \fp_cos_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_cos:Nn { c }
+\cs_generate_variant:Nn \fp_gcos:Nn { c }
+\cs_new_protected_nopar:Npn \fp_cos_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_trig_arg_tl
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \etex_ifcsname:D c_fp_cos ( \l_fp_trig_arg_tl ) _tl \tex_endcsname:D
+ \tex_else:D
+ \exp_after:wN \fp_cos_aux_i:
+ \tex_fi:D
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_cos ( \l_fp_trig_arg_tl ) _tl } }
+ }
+ \fp_tmp:w
+}
+% \end{macrocode}
+% Almost the same as for sine: just a bit of correction for the sign
+% of the output.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_cos_aux_i: {
+ \fp_trig_normalise:
+ \fp_cos_aux_ii:
+ \tex_ifnum:D \l_fp_output_integer_int = \c_one
+ \l_fp_output_exponent_int \c_zero
+ \tex_else:D
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_decimal_int \l_fp_output_extended_int
+ \l_fp_output_exponent_int -\c_nine
+ \tex_fi:D
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_cos ( \l_fp_trig_arg_tl ) _tl }
+ \tl_set:cx { c_fp_cos ( \l_fp_trig_arg_tl ) _tl }
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int > \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+}
+\cs_new_protected_nopar:Npn \fp_cos_aux_ii: {
+ \tex_ifcase:D \l_fp_trig_octant_int
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_cos:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_sin:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_sin:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_cos:
+ \tex_fi:D
+ \tex_ifnum:D \l_fp_input_a_sign_int > \c_zero
+ \tex_ifnum:D \l_fp_trig_octant_int > \c_two
+ \l_fp_input_a_sign_int \c_minus_one
+ \tex_fi:D
+ \tex_else:D
+ \tex_ifnum:D \l_fp_trig_octant_int > \c_two
+ \tex_else:D
+ \l_fp_input_a_sign_int \c_one
+ \tex_fi:D
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
%
-%\subsection{Fixed-point conditionals}
+%\begin{macro}{\fp_trig_calc_cos:}
+%\begin{macro}{\fp_trig_calc_sin:}
+%\begin{macro}[aux]{\fp_trig_calc_aux:}
+% These functions actually do the calculation for sine and cosine.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_calc_cos: {
+ \tex_ifnum:D \l_fp_input_a_decimal_int = \c_zero
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \tex_else:D
+ \l_fp_trig_sign_int \c_minus_one
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \c_two
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int \c_three
+ \tex_ifnum:D \l_fp_trig_extended_int = \c_zero
+ \tex_ifnum:D \l_fp_trig_decimal_int = \c_zero
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \tex_else:D
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_one_thousand_million
+ \l_fp_output_extended_int \c_zero
+ \tex_fi:D
+ \tex_else:D
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int 999999999 \scan_stop:
+ \l_fp_output_extended_int \c_one_thousand_million
+ \tex_fi:D
+ \tex_advance:D \l_fp_output_extended_int -\l_fp_trig_extended_int
+ \tex_advance:D \l_fp_output_decimal_int -\l_fp_trig_decimal_int
+ \exp_after:wN \fp_trig_calc_aux:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_calc_sin: {
+ \l_fp_output_integer_int \c_zero
+ \tex_ifnum:D \l_fp_input_a_decimal_int = \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \tex_else:D
+ \l_fp_output_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_output_extended_int \l_fp_input_a_extended_int
+ \l_fp_trig_sign_int \c_one
+ \l_fp_trig_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_trig_extended_int \l_fp_input_a_extended_int
+ \l_fp_count_int \c_two
+ \exp_after:wN \fp_trig_calc_aux:
+ \tex_fi:D
+}
+% \end{macrocode}
+% This implements a Taylor series calculation for the trigonometric
+% functions. Lots of shuffling about as \TeX\ is not exactly a natural
+% choice for this sort of thing.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_calc_aux: {
+ \l_fp_trig_sign_int -\l_fp_trig_sign_int
+ \fp_mul:NNNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_mul:NNNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \tex_advance:D \l_fp_count_int \c_one
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \tex_advance:D \l_fp_count_int \c_one
+ \tex_ifnum:D \l_fp_trig_decimal_int > \c_zero
+ \tex_ifnum:D \l_fp_trig_sign_int > \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \l_fp_trig_decimal_int
+ \tex_advance:D \l_fp_output_extended_int
+ \l_fp_trig_extended_int
+ \tex_ifnum:D \l_fp_output_extended_int < \c_one_thousand_million
+ \tex_else:D
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \tex_advance:D \l_fp_output_extended_int
+ -\c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D \l_fp_output_decimal_int < \c_one_thousand_million
+ \tex_else:D
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int
+ -\c_one_thousand_million
+ \tex_fi:D
+ \tex_else:D
+ \tex_advance:D \l_fp_output_decimal_int -\l_fp_trig_decimal_int
+ \tex_advance:D \l_fp_output_extended_int
+ -\l_fp_input_a_extended_int
+ \tex_ifnum:D \l_fp_output_extended_int < \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \c_minus_one
+ \tex_advance:D \l_fp_output_extended_int \c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D \l_fp_output_decimal_int < \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_minus_one
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \tex_fi:D
+ \tex_fi:D
+ \exp_after:wN \fp_trig_calc_aux:
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_tan:Nn}
+%\begin{macro}{\fp_tan:cn}
+%\begin{macro}{\fp_gtan:Nn}
+%\begin{macro}{\fp_gtan:cn}
+%\begin{macro}[aux]{\fp_tan_aux:NNn}
+%\begin{macro}[aux]{\fp_tan_aux_i:}
+%\begin{macro}[aux]{\fp_tan_aux_ii:}
+%\begin{macro}[aux]{\fp_tan_aux_iii:}
+%\begin{macro}[aux]{\fp_tan_aux_iv:}
+% As might be expected, tangents are calculated from the sine and cosine
+% by division. So there is a bit of set up, the two subsidiary pieces
+% of work are done and then a division takes place. For small numbers,
+% the same approach is used as for sines, with the input value simply
+% returned as is.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_tan:Nn {
+ \fp_tan_aux:NNn \tl_set:Nn
+}
+\cs_new_protected_nopar:Npn \fp_gtan:Nn {
+ \fp_tan_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_tan:Nn { c }
+\cs_generate_variant:Nn \fp_gtan:Nn { c }
+\cs_new_protected_nopar:Npn \fp_tan_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_trig_arg_tl
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \tex_ifnum:D \l_fp_input_a_exponent_int < -\c_five
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \l_fp_trig_arg_tl }
+ }
+ \tex_else:D
+ \etex_ifcsname:D
+ c_fp_tan ( \l_fp_trig_arg_tl ) _tl
+ \tex_endcsname:D
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_i:
+ \tex_fi:D
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_tan ( \l_fp_trig_arg_tl ) _tl } }
+ }
+ \tex_fi:D
+ \fp_tmp:w
+}
+% \end{macrocode}
+% The business of the calculation does not check for stored sines or
+% cosines as there would then be an overhead to reading them back in.
+% There is also no need to worry about `small' sine values as
+% these will have been dealt with earlier. There is a two-step lead off
+% so that undefined division is not even attempted.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_tan_aux_i: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int < \c_ten
+ \exp_after:wN \fp_tan_aux_ii:
+ \tex_else:D
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ \c_zero_fp
+ \exp_after:wN \fp_trig_overflow_msg:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_tan_aux_ii: {
+ \fp_trig_normalise:
+ \fp_cos_aux_ii:
+ \tex_ifnum:D \l_fp_input_a_decimal_int = \c_zero
+ \tex_ifnum:D \l_fp_input_a_integer_int = \c_zero
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ \c_undefined_fp
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_iii:
+ \tex_fi:D
+ \tex_else:D
+ \exp_after:wN \fp_tan_aux_iii:
+ \tex_fi:D
+}
+% \end{macrocode}
+% The division is done here using the same code as the standard division
+% unit, shifting the digits in the calculated sine and cosine to
+% maintain accuracy.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_tan_aux_iii: {
+ \l_fp_input_b_integer_int \l_fp_output_decimal_int
+ \l_fp_input_b_decimal_int \l_fp_output_extended_int
+ \l_fp_input_b_exponent_int -\c_nine
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_sin_aux_ii:
+ \l_fp_input_a_integer_int \l_fp_output_decimal_int
+ \l_fp_input_a_decimal_int \l_fp_output_extended_int
+ \l_fp_input_a_exponent_int -\c_nine
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tex_ifnum:D \l_fp_input_a_decimal_int = \c_zero
+ \tex_ifnum:D \l_fp_input_a_integer_int = \c_zero
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ \c_zero_fp
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_iv:
+ \tex_fi:D
+ \tex_else:D
+ \exp_after:wN \fp_tan_aux_iv:
+ \tex_fi:D
+}
+ \cs_new_protected_nopar:Npn \fp_tan_aux_iv: {
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
+ \l_fp_div_offset_int \c_one_hundred_million
+ \fp_div_loop:
+ \l_fp_output_exponent_int
+ \etex_numexpr:D
+ \l_fp_input_a_exponent_int - \l_fp_input_b_exponent_int
+ \scan_stop:
+ \tex_ifnum:D \l_fp_trig_octant_int < \c_three
+ \l_fp_output_sign_int \c_one
+ \tex_else:D
+ \l_fp_output_sign_int \c_minus_one
+ \tex_fi:D
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ \tl_set:cx { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ {
+ \tex_ifnum:D \l_fp_output_sign_int > \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{Tests for special values}
+%
+%\begin{macro}{\fp_if_infinity_p:N}
+%\begin{macro}[TF]{\fp_if_infinity:N}
+% Testing for infinity is easy.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \fp_if_infinity:N #1 { p , T , F , TF } {
+ \tex_ifx:D #1 \c_infinity_fp
+ \prg_return_true:
+ \tex_else:D
+ \prg_return_false:
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_if_undefined_p:N}
+%\begin{macro}[TF]{\fp_if_undefined:N}
+% Testing for an undefined value is easy.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF } {
+ \tex_ifx:D #1 \c_undefined_fp
+ \prg_return_true:
+ \tex_else:D
+ \prg_return_false:
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\fp_if_zero_p:N}
+%\begin{macro}[TF]{\fp_if_zero:N}
+% Testing for a zero fixed-point is also easy.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF } {
+ \tex_ifx:D #1 \c_zero_fp
+ \prg_return_true:
+ \tex_else:D
+ \prg_return_false:
+ \tex_fi:D
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{Floating-point conditionals}
%
%\begin{macro}[TF]{\fp_compare:nNn}
%\begin{macro}[TF]{\fp_compare:NNN}
@@ -1900,20 +3786,31 @@
% faster. The lead off for both is the same: get the two numbers
% read and then look for a function to handle the comparison.
% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \fp_compare:nNn #1#2#3
- { T , F , TF } {
+\prg_new_protected_conditional:Npnn \fp_compare:nNn #1#2#3 { T , F , TF }
+ {
\group_begin:
\fp_split:Nn a {#1}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
\fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
\fp_compare_aux:N #2
}
-\prg_new_protected_conditional:Npnn \fp_compare:NNN #1#2#3
- { T , F , TF } {
+\prg_new_protected_conditional:Npnn \fp_compare:NNN #1#2#3 { T , F , TF }
+ {
\group_begin:
\fp_read:N #3
- \l_fp_input_b_sign_int \l_fp_input_a_sign_int
- \l_fp_input_b_integer_int \l_fp_input_a_integer_int
- \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \l_fp_input_b_integer_int \l_fp_input_a_integer_int
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_exponent_int \l_fp_input_a_exponent_int
\fp_read:N #1
\fp_compare_aux:N #2
}
@@ -1933,8 +3830,14 @@
\tex_ifnum:D \l_fp_input_a_sign_int = \l_fp_input_b_sign_int
\tex_ifnum:D \l_fp_input_a_integer_int = \l_fp_input_b_integer_int
\tex_ifnum:D \l_fp_input_a_decimal_int = \l_fp_input_b_decimal_int
- \group_end:
- \prg_return_true:
+ \tex_ifnum:D
+ \l_fp_input_a_exponent_int = \l_fp_input_b_exponent_int
+ \group_end:
+ \prg_return_true:
+ \tex_else:D
+ \group_end:
+ \prg_return_false:
+ \tex_fi:D
\tex_else:D
\group_end:
\prg_return_false:
@@ -1949,8 +3852,8 @@
\tex_fi:D
}
% \end{macrocode}
-% For comparitors life is a lot moe complex, as there are three cases for
-% the integer part (equality as well as greater and less than). The
+% For comparators life is a lot more complex, as there are three cases
+% for the integer part (equality as well as greater and less than). The
% code here is quite repetitive to keep speed up, and simply does
% exhaustive checks.
% \begin{macrocode}
@@ -1989,353 +3892,84 @@
\tex_fi:D
}
\cs_new_protected_nopar:cpn { fp_compare_absolute_a > b: } {
- \tex_ifnum:D \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
+ \tex_ifnum:D \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
\group_end:
- \prg_return_true:
- \tex_else:D
- \tex_ifnum:D \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
- \group_end:
- \prg_return_false:
- \tex_else:D
- \tex_ifnum:D \l_fp_input_a_decimal_int > \l_fp_input_b_decimal_int
+ \prg_return_true:
+ \tex_else:D
+ \tex_ifnum:D \l_fp_input_a_exponent_int < \l_fp_input_b_exponent_int
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
\group_end:
\prg_return_true:
\tex_else:D
\group_end:
\prg_return_false:
\tex_fi:D
+ \tex_else:D
+ \tex_ifnum:D \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
+ \group_end:
+ \prg_return_true:
+ \tex_else:D
+ \tex_ifnum:D
+ \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
+ \group_end:
+ \prg_return_false:
+ \tex_else:D
+ \tex_ifnum:D
+ \l_fp_input_a_decimal_int > \l_fp_input_b_decimal_int
+ \group_end:
+ \prg_return_true:
+ \tex_else:D
+ \group_end:
+ \prg_return_false:
+ \tex_fi:D
+ \tex_fi:D
+ \tex_fi:D
\tex_fi:D
\tex_fi:D
}
\cs_new_protected_nopar:cpn { fp_compare_absolute_a < b: } {
- \tex_ifnum:D \l_fp_input_b_integer_int > \l_fp_input_a_integer_int
- \group_end:
- \prg_return_true:
- \tex_else:D
- \tex_ifnum:D \l_fp_input_b_integer_int < \l_fp_input_a_integer_int
+ \tex_ifnum:D \l_fp_input_b_exponent_int > \l_fp_input_a_exponent_int
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
\group_end:
\prg_return_false:
\tex_else:D
- \tex_ifnum:D \l_fp_input_b_decimal_int > \l_fp_input_a_decimal_int
+ \group_end:
+ \prg_return_true:
+ \tex_fi:D
+ \tex_else:D
+ \tex_ifnum:D \l_fp_input_b_exponent_int < \l_fp_input_a_exponent_int
+ \group_end:
+ \prg_return_false:
+ \tex_else:D
+ \tex_ifnum:D \l_fp_input_b_integer_int > \l_fp_input_a_integer_int
\group_end:
\prg_return_true:
\tex_else:D
- \group_end:
- \prg_return_false:
- \tex_fi:D
- \tex_fi:D
- \tex_fi:D
-}
-% \end{macrocode}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%
-%\subsection{Formatting fixed point numbers}
-%
-% When transferring fixed points to higher level code it is desirable
-% to allow flexible formatting.
-%
-%\begin{macro}{\l_fp_round_precision_int}
-%\begin{macro}{\l_fp_remove_zeros_bool}
-%\begin{macro}{\l_fp_round_mode_tl}
-% \begin{macrocode}
-\keys_define:nn { fp } {
- precision .int_set:N = \l_fp_round_precision_int ,
- remove-trailing-zeros .bool_set:N = \l_fp_remove_zeros_bool ,
- round-mode .choice: ,
- round-mode
- / half-even .tl_set:N = \l_fp_round_mode_tl ,
- round-mode
- / half-from-zero .tl_set:N = \l_fp_round_mode_tl ,
- round-mode
- / none .tl_set:N = \l_fp_round_mode_tl ,
- round-mode
- / truncate .tl_set:N = \l_fp_round_mode_tl ,
-}
-\keys_set:nn { fp } {
- precision = 9 ,
- remove-trailing-zeros = true ,
- round-mode = none ,
-}
-% \end{macrocode}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%
-%\begin{macro}{\fp_to_tl:NN}
-%\begin{macro}{\fp_to_tl:Nc}
-%\begin{macro}{\fp_to_tl:cN}
-%\begin{macro}{\fp_to_tl:cc}
-%\begin{macro}{\fp_gto_tl:NN}
-%\begin{macro}{\fp_gto_tl:Nc}
-%\begin{macro}{\fp_gto_tl:cN}
-%\begin{macro}{\fp_gto_tl:cc}
-%\begin{macro}[aux]{\fp_to_tl_aux:NNN}
-%\begin{macro}[aux]{\fp_remove_zeros:NNNNNNNNN}
-%\begin{macro}[aux]{\fp_remove_zeros_aux:w}
-%\begin{macro}[aux]{\fp_round_half-from-zero:}
-%\begin{macro}[aux]{\fp_round_from_zero:}
-%\begin{macro}[aux]{\fp_round_from_zero_aux:NNNNNNNNN}
-%\begin{macro}[aux]{\fp_round_from_zero_decimal:N}
-%\begin{macro}[aux]{\fp_round_from_zero_integer:}
-%\begin{macro}[aux]{\fp_round_half-even:}
-%\begin{macro}[aux]{\fp_round_even:}
-%\begin{macro}[aux]{\fp_round_even_aux:NNNNNNNNN}
-%\begin{macro}[aux]{\fp_round_even_decimal:N}
-%\begin{macro}[aux]{\fp_round_even_integer:}
-%\begin{macro}[aux]{\fp_round_none:}
-%\begin{macro}[aux]{\fp_round_truncate:}
-% The usual lead off with a series of wrapper functions.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \fp_to_tl:NN {
- \fp_to_tl_aux:NNN \tl_set:Nn
-}
-\cs_new_protected_nopar:Npn \fp_gto_tl:NN {
- \fp_to_tl_aux:NNN \tl_gset:Nn
-}
-\cs_generate_variant:Nn \fp_to_tl:NN { Nc }
-\cs_generate_variant:Nn \fp_to_tl:NN { c }
-\cs_generate_variant:Nn \fp_to_tl:NN { cc }
-\cs_generate_variant:Nn \fp_gto_tl:NN { Nc }
-\cs_generate_variant:Nn \fp_gto_tl:NN { c }
-\cs_generate_variant:Nn \fp_gto_tl:NN { cc }
-% \end{macrocode}
-% The main body of the conversion follows the pattern of reading the
-% \texttt{fp} then processing it. Rounding takes place first, so
-% that zero stripping is easier. This may involve loosing the decimal
-% part entirely.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \fp_to_tl_aux:NNN #1#2#3 {
- \group_begin:
- \fp_read:N #2
- \use:c { fp_round_ \l_fp_round_mode_tl :}
- \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
- {
- \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
- -
- \tex_fi:D
- \int_use:N \l_fp_input_a_integer_int
- \intexpr_compare:nNnT { \l_fp_round_precision_int } > { \c_zero }
- {
- .
- \bool_if:NTF \l_fp_remove_zeros_bool
- {
- \exp_after:wN \use_i:nn
- \exp_after:wN \fp_remove_zeros:NNNNNNNNN
- }
- { \exp_after:wN \use_none:n }
- \int_use:N \l_fp_input_a_decimal_int
- }
- }
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #3 \exp_after:wN { \l_fp_tmp_tl }
-}
-% \end{macrocode}
-% For removing zeros, the code above ensures there will be exactly
-% \( 9 \) tokens to deal with. The idea here is to go through them one
-% at a time and see if the remained is equal to zero. The input can
-% then be discarded if the precision in the output is correct. Speed
-% is not quite so vital here so everything is coded in \LaTeX3 rather
-% than primitives. This approach avoids needing to reverse the input.
-% \begin{macrocode}
-\cs_new_nopar:Npn \fp_remove_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
- \fp_remove_zeros_aux:w #1#2#3#4#5#6#7#8#9 \q_stop 1
-}
-\cs_new_nopar:Npn \fp_remove_zeros_aux:w #1#2 \q_stop #3 {
- #1
- \intexpr_compare:nNnTF { 0 #2 } = { \c_zero }
- {
- \intexpr_compare:nNnF { \l_fp_round_precision_int } < { #3 + 1 }
- {
- \intexpr_compare:nNnT {#3} < { 9 }
- { \fp_remove_zeros_aux:w #2 \q_stop { #3 + 1 } }
- }
- }
- {
- \intexpr_compare:nNnT {#3} < { 9 }
- { \fp_remove_zeros_aux:w #2 \q_stop { #3 + 1 } }
- }
-}
-% \end{macrocode}
-% Rounding away from zero is relatively easy, as it only depends on
-% the digit immediately before the rounded position. The code here
-% therefore does a fast reversal of the direct of the input, then
-% checks the position before considering the size of the digit itself.
-% The position here refers to the digit that will be rounded, which is
-% therefore out by one from the digit being considered during the loop.
-% \begin{macrocode}
-\cs_new_protected_nopar:cpn { fp_round_half-from-zero: } {
- \tex_ifnum:D \l_fp_round_precision_int < \c_nine
- \exp_after:wN \fp_round_from_zero:
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_round_from_zero: {
- \bool_set_false:N \l_fp_round_carry_bool
- \l_fp_round_position_int \c_eight
- \tl_clear:N \l_fp_round_decimal_tl
- \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \exp_after:wN \use_i:nn \exp_after:wN
- \fp_round_from_zero_aux:NNNNNNNNN
- \int_use:N \l_fp_input_a_decimal_int
-}
-\cs_new_protected_nopar:Npn \fp_round_from_zero_aux:NNNNNNNNN
- #1#2#3#4#5#6#7#8#9 {
- \fp_round_from_zero_decimal:N #9#8#7#6#5#4#3#2#1
- \fp_round_from_zero_integer:
-}
-\cs_new_protected_nopar:Npn \fp_round_from_zero_decimal:N #1 {
- \tex_ifnum:D \l_fp_round_position_int < \l_fp_round_precision_int
- \bool_if:NTF \l_fp_round_carry_bool
- { \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop: }
- { \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop: }
- \tex_ifnum:D \l_fp_tmp_int = \c_ten
- \l_fp_tmp_int \c_zero
- \tex_else:D
- \bool_set_false:N \l_fp_round_carry_bool
- \tex_fi:D
- \tl_set:Nx \l_fp_round_decimal_tl
- { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
- \tex_else:D
- \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
- \tex_ifnum:D \l_fp_round_position_int = \l_fp_round_precision_int
- \tex_ifnum:D #1 > \c_four
- \bool_set_true:N \l_fp_round_carry_bool
- \tex_fi:D
- \tex_fi:D
- \tex_fi:D
- \tex_advance:D \l_fp_round_position_int \c_minus_one
- \tex_ifnum:D \l_fp_round_position_int > \c_minus_one
- \exp_after:wN \fp_round_from_zero_decimal:N
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_round_from_zero_integer: {
- \bool_if:NT \l_fp_round_carry_bool
- { \tex_advance:D \l_fp_input_a_integer_int \c_one }
- \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
-}
-% \end{macrocode}
-% The general outline is similar when rounding where ties go to the
-% nearest even number. However, life is more complicated as there is a
-% need to track the discarded digits, and to see whether the digit to
-% round is odd or even. This is done by tracking the discarded digits.
-% When reaching the digit to check for rounding, the discards are used
-% to indicate if there is an exact half to take into account. When the
-% rounding takes place without an exact half, things are the same as
-% for the `away from zero' approach. When rounding an exact
-% half, there is an odd/even test before applying any modification.
-% \begin{macrocode}
-\cs_new_protected_nopar:cpn { fp_round_half-even: } {
- \tex_ifnum:D \l_fp_round_precision_int < \c_nine
- \exp_after:wN \fp_round_even:
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_round_even: {
- \bool_set_false:N \l_fp_round_carry_bool
- \l_fp_round_position_int \c_eight
- \tl_clear:N \l_fp_round_decimal_tl
- \int_zero:N \l_fp_round_discard_int
- \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \exp_after:wN \use_i:nn \exp_after:wN
- \fp_round_even_aux:NNNNNNNNN
- \int_use:N \l_fp_input_a_decimal_int
-}
-\cs_new_protected_nopar:Npn \fp_round_even_aux:NNNNNNNNN
- #1#2#3#4#5#6#7#8#9 {
- \fp_round_even_decimal:N #9#8#7#6#5#4#3#2#1
- \fp_round_even_integer:
-}
-\cs_new_protected_nopar:Npn \fp_round_even_decimal:N #1 {
- \tex_ifnum:D \l_fp_round_position_int < \l_fp_round_precision_int
- \bool_if:NTF \l_fp_round_carry_bool
- {
- \tex_ifnum:D \l_fp_round_discard_int = \c_zero
- \l_fp_round_discard_int \c_one
- \tex_ifodd:D #1 \scan_stop:
- \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop:
+ \tex_ifnum:D
+ \l_fp_input_b_integer_int < \l_fp_input_a_integer_int
+ \group_end:
+ \prg_return_false:
+ \tex_else:D
+ \tex_ifnum:D
+ \l_fp_input_b_decimal_int > \l_fp_input_a_decimal_int
+ \group_end:
+ \prg_return_true:
\tex_else:D
- \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop:
+ \group_end:
+ \prg_return_false:
\tex_fi:D
- \tex_else:D
- \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop:
- \tex_fi:D
- }
- { \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop: }
- \tex_ifnum:D \l_fp_tmp_int = \c_ten
- \l_fp_tmp_int \c_zero
- \tex_else:D
- \bool_set_false:N \l_fp_round_carry_bool
- \tex_fi:D
- \tl_set:Nx \l_fp_round_decimal_tl
- { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
- \tex_else:D
- \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
- \tex_ifnum:D \l_fp_round_position_int = \l_fp_round_precision_int
- \tex_ifnum:D #1 > \c_four
- \bool_set_true:N \l_fp_round_carry_bool
- \tex_ifnum:D #1 = \c_five
- \tex_else:D
- \l_fp_round_discard_int \c_one
\tex_fi:D
\tex_fi:D
- \tex_else:D
- \tex_advance:D \l_fp_round_discard_int #1 \scan_stop:
- \tex_fi:D
- \tex_fi:D
- \tex_advance:D \l_fp_round_position_int \c_minus_one
- \tex_ifnum:D \l_fp_round_position_int > \c_minus_one
- \exp_after:wN \fp_round_even_decimal:N
+ \tex_fi:D
\tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_round_even_integer: {
- \bool_if:NT \l_fp_round_carry_bool
- {
- \tex_ifnum:D \l_fp_round_discard_int = \c_zero
- \tex_ifodd:D \l_fp_input_a_integer_int
- \tex_advance:D \l_fp_input_a_integer_int \c_one
- \tex_fi:D
- \tex_else:D
- \tex_advance:D \l_fp_input_a_integer_int \c_one
- \tex_fi:D
- }
- \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
-}
-% \end{macrocode}
-% The only task that is needed when not rounding is to ensure that
-% the zero-stripping function will remove things reliably. This is
-% done by setting the precision to one digit: no rounding will always
-% leave at least one decimal digit, even if it is zero.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \fp_round_none: {
- \l_fp_round_precision_int \c_one
-}
-% \end{macrocode}
-% Truncating input is done by using the \cs{tex_divide:D} primitive
-% as this turns out to be the most convenient method to do this.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \fp_round_truncate: {
- \intexpr_compare:nNnF { \l_fp_round_precision_int } > { 8 }
- {
- \intexpr_compare:nNnTF { \l_fp_round_precision_int } < { 1 }
- { \l_fp_input_a_decimal_int \c_zero \scan_stop: }
- {
- \int_set:Nn \l_fp_tmp_int
- {
- \prg_replicate:nn { 9 - \l_fp_round_precision_int }
- { 10 * }
- 1
- }
- \tex_divide:D \l_fp_input_a_decimal_int \l_fp_tmp_int
- \tex_multiply:D \l_fp_input_a_decimal_int \l_fp_tmp_int
- }
- }
-}
+
% \end{macrocode}
%\end{macro}
%\end{macro}
@@ -2345,43 +3979,39 @@
%\end{macro}
%\end{macro}
%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
-%\end{macro}
%
%\subsection{Messages}
%
-%\begin{macro}{\fp_msg_overflow:}
-% To avoid expansion issues above, the messages are all set up as
-% functions.
+%\begin{macro}{\fp_overflow_msg:}
+% A generic overflow message, used whenever there is a possible
+% overflow.
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \fp_msg_overflow: {
+\msg_kernel_new:nnnn { fpu } { overflow }
+ { Number~too~big. }
+ {
+ The~input~given~is~too~big~for~the~LaTeX~floating~point~unit. \\
+ Further~errors~may~well~occur!
+ }
+\cs_new_protected_nopar:Npn \fp_overflow_msg: {
\msg_kernel_error:nn { fpu } { overflow }
-}
+}
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{\fp_trig_overflow_msg:}
+% A slightly more helpful message for trigonometric overflows.
% \begin{macrocode}
-\msg_kernel_new:nnnn { fpu } { overflow }
- { Arithmetic~overflow. }
+\msg_kernel_new:nnnn { fpu } { trigonometric-overflow }
+ { Number~too~big~for~trigonometry~unit. }
{
- The~calculation~requested~exceeds~the~capacity \\
- of~the~fixed-point~unit.
+ The~trigonometry~code~can~only~work~with~numbers~smaller~
+ than~1000000000.
}
+\cs_new_protected_nopar:Npn \fp_trig_overflow_msg: {
+ \msg_kernel_error:nn { fpu } { trigonometric-overflow }
+}
% \end{macrocode}
-%
+%\end{macro}%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/expl3/l3prg.dtx b/Master/texmf-dist/source/latex/expl3/l3prg.dtx
index 4ea121eb1f4..29dcded112d 100644
--- a/Master/texmf-dist/source/latex/expl3/l3prg.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3prg.dtx
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3prg.dtx 1853 2010-03-21 09:11:08Z joseph $
+\GetIdInfo$Id: l3prg.dtx 1992 2010-08-04 20:41:40Z joseph $
{L3 Experimental control structures}
%\iffalse
%<*driver>
@@ -619,6 +619,53 @@
% Returns the type of <variable> (\texttt{tl}, \texttt{int}, etc.)
%\end{function}
%
+%\subsection{Mapping to variables}
+%
+%\begin{function}{ \prg_new_map_functions:Nn }
+% \begin{syntax}
+% \cs{prg_new_map_functions:Nn} \meta{token} \Arg{name}
+% \end{syntax}
+% Creates a family of mapping functions which can be applied to
+% a token list, dividing the list up at each occurance of the
+% \meta{token}. The functions defined will be
+% \begin{itemize}
+% \item \cs{\meta{name}_map_function:NN}
+% \item \cs{\meta{name}_map_function:nN}
+% \item \cs{\meta{name}_map_inline:Nn}
+% \item \cs{\meta{name}_map_inline:nn}
+% \item \cs{\meta{name}_map_break:}
+% \end{itemize}
+% Of these, the \texttt{inline} functions are not expandable but
+% the other functions can be used in expansion contexts. The use of
+% each function is best illustrated by the \cs{clist_map_\ldots}
+% family defined by \LaTeX3 itself for mapping to comma-separated
+% lists. An error will be raised if the \meta{name} has already been
+% used to generate a family of mapping functions. All of the
+% definitions are created globally.
+%\end{function}
+%
+%\begin{function}{ \prg_set_map_functions:Nn }
+% \begin{syntax}
+% \cs{prg_set_map_functions:Nn} \meta{token} \Arg{name}
+% \end{syntax}
+% Creates a family of mapping functions which can be applied to
+% a token list, dividing the list up at each occurance of the
+% \meta{token}. The functions defined will be
+% \begin{itemize}
+% \item \cs{\meta{name}_map_function:NN}
+% \item \cs{\meta{name}_map_function:nN}
+% \item \cs{\meta{name}_map_inline:Nn}
+% \item \cs{\meta{name}_map_inline:nn}
+% \item \cs{\meta{name}_map_break:}
+% \end{itemize}
+% Of these, the \texttt{inline} functions are not expandable but
+% the other functions can be used in expansion contexts. The use of
+% each function is best illustrated by the \cs{clist_map_\ldots}
+% family defined by \LaTeX3 itself for mapping to comma-separated
+% lists. Any existing defintions for the \meta{name} will be
+% overwritten. All of the definitions are created globally.
+%\end{function}
+%
% \end{documentation}
%
% \begin{implementation}
@@ -1774,6 +1821,104 @@
%\end{macro}
%\end{macro}
%
+%\subsection{Mapping to variables}
+%
+%\begin{macro}{\prg_new_map_functions:Nn}
+%\begin{macro}{\prg_set_map_functions:Nn}
+% The idea here is to generate all of the various mapping functions
+% in one go. Everything is done with expansion so that the performance
+% hit is taken at definition time and not at point of use. The inline
+% version uses a counter as this keeps things nestable, and global to
+% avoid problems with, for example, table cells.
+% \begin{macrocode}
+\cs_new_protected:Npn \prg_new_map_functions:Nn #1#2 {
+ \cs_if_free:cTF { #2 _map_function:NN }
+ { \prg_set_map_functions:Nn #1 {#2} }
+ {
+ \msg_kernel_error:nnx { code } { csname-already-defined }
+ { \token_to_str:c { #2 _map_function:NN } }
+ }
+}
+\cs_new_protected:Npn \prg_set_map_functions:Nn #1#2 {
+ \cs_gset_nopar:cpx { #2 _map_function:NN } ##1##2
+ {
+ \exp_not:N \tl_if_empty:NF ##1
+ {
+ \exp_not:N \exp_after:wN
+ \exp_not:c { #2 _map_function_aux:Nw }
+ \exp_not:N \exp_after:wN ##2 ##1
+ \exp_not:n { #1 \q_recursion_tail #1 \q_recursion_stop }
+ }
+ }
+ \cs_gset:cpx { #2 _map_function:nN } ##1##2
+ {
+ \exp_not:N \tl_if_blank:nF {##1}
+ {
+ \exp_not:c { #2 _map_function_aux:Nw } ##2 ##1
+ \exp_not:n { #1 \q_recursion_tail #1 \q_recursion_stop }
+ }
+ }
+ \cs_gset:cpx { #2 _map_function_aux:Nw } ##1##2 #1
+ {
+ \exp_not:N \quark_if_recursion_tail_stop:n {##2}
+ ##1 {##2}
+ \exp_not:c { #2 _map_function_aux:Nw } ##1
+ }
+ \cs_if_free:cT { g_ #2 _map_inline_int }
+ { \int_new:c { g_ #2 _map_inline_int } }
+ \cs_gset_protected_nopar:cpx { #2 _map_inline:Nn } ##1##2
+ {
+ \exp_not:N \tl_if_empty:NF ##1
+ {
+ \exp_not:N \int_gincr:N \exp_not:c { g_ #2 _map_inline_int }
+ \cs_gset:cpn
+ {
+ #2 _map_inline_
+ \exp_not:N \int_use:N \exp_not:c { g_ #2 _map_inline_int }
+ :n
+ }
+ ####1 {##2}
+ \exp_not:N \exp_last_unbraced:NcV
+ \exp_not:c { #2 _map_function_aux:Nw }
+ {
+ #2 _map_inline_
+ \exp_not:N \int_use:N \exp_not:c { g_ #2 _map_inline_int }
+ :n
+ }
+ ##1 \exp_not:n { #1 \q_recursion_tail #1 \q_recursion_stop }
+ \exp_not:N \int_gdecr:N \exp_not:c { g_ #2 _map_inline_int }
+ }
+ }
+ \cs_gset_protected:cpx { #2 _map_inline:nn } ##1##2
+ {
+ \exp_not:N \tl_if_empty:nF {##1}
+ {
+ \exp_not:N \int_gincr:N \exp_not:c { g_ #2 _map_inline_int }
+ \cs_gset:cpn
+ {
+ #2 _map_inline_
+ \exp_not:N \int_use:N \exp_not:c { g_ #2 _map_inline_int }
+ :n
+ }
+ ####1 {##2}
+ \exp_not:N \exp_args:Nc
+ \exp_not:c { #2 _map_function_aux:Nw }
+ {
+ #2 _map_inline_
+ \exp_not:N \int_use:N \exp_not:c { g_ #2 _map_inline_int }
+ :n
+ }
+ ##1 \exp_not:n { #1 \q_recursion_tail #1 \q_recursion_stop }
+ \exp_not:N \int_gdecr:N \exp_not:c { g_ #2 _map_inline_int }
+ }
+ }
+ \cs_gset_eq:cN { #2 _map_break: }
+ \use_none_delimit_by_q_recursion_stop:w
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
% That's it (for now).
% \begin{macrocode}
%</initex|package>
diff --git a/Master/texmf-dist/tex/latex/expl3/expl3.sty b/Master/texmf-dist/tex/latex/expl3/expl3.sty
index 63917163f94..8ab93d24188 100644
--- a/Master/texmf-dist/tex/latex/expl3/expl3.sty
+++ b/Master/texmf-dist/tex/latex/expl3/expl3.sty
@@ -49,7 +49,7 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
-\GetIdInfo$Id: expl3.dtx 1987 2010-07-25 14:55:46Z joseph $
+\GetIdInfo$Id: expl3.dtx 2020 2010-09-14 10:37:46Z joseph $
{L3 Experimental code bundle wrapper}%
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
@@ -78,7 +78,7 @@
l3prop,
l3msg,
l3io,
- l3skip,
+ l3skip
}
\RequirePackage{
l3box,
@@ -88,7 +88,7 @@
l3xref,
l3file,
l3fp,
- l3luatex,
+ l3luatex
}
\RequirePackage{calc}
\bool_if:nT { \@l@expl@check@declarations@bool } {
diff --git a/Master/texmf-dist/tex/latex/expl3/l3basics.sty b/Master/texmf-dist/tex/latex/expl3/l3basics.sty
index b0535e6833a..785b120b2dc 100644
--- a/Master/texmf-dist/tex/latex/expl3/l3basics.sty
+++ b/Master/texmf-dist/tex/latex/expl3/l3basics.sty
@@ -48,7 +48,7 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
-\GetIdInfo$Id: l3basics.dtx 1942 2010-06-07 17:06:11Z will $
+\GetIdInfo$Id: l3basics.dtx 1992 2010-08-04 20:41:40Z joseph $
{L3 Experimental basic definitions}
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
@@ -488,7 +488,7 @@
\cs_tmp:w \cs_new_protected:Npn \cs_gset_protected:Npn
\cs_tmp:w \cs_new_protected:Npx \cs_gset_protected:Npx
\cs_set:Npn \cs_tmp:w #1#2{
- \cs_new_nopar:Npn #1 { \exp_args:Nc #2 }
+ \cs_new_protected_nopar:Npn #1 { \exp_args:Nc #2 }
}
\cs_tmp:w \cs_set_nopar:cpn \cs_set_nopar:Npn
\cs_tmp:w \cs_set_nopar:cpx \cs_set_nopar:Npx
diff --git a/Master/texmf-dist/tex/latex/expl3/l3box.sty b/Master/texmf-dist/tex/latex/expl3/l3box.sty
index 69baad3296b..484e7c4a635 100644
--- a/Master/texmf-dist/tex/latex/expl3/l3box.sty
+++ b/Master/texmf-dist/tex/latex/expl3/l3box.sty
@@ -48,7 +48,7 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
-\GetIdInfo$Id: l3box.dtx 1919 2010-05-22 05:56:38Z will $
+\GetIdInfo$Id: l3box.dtx 2015 2010-09-03 17:45:09Z mittelba $
{L3 Experimental Box module}
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
@@ -119,10 +119,15 @@
\cs_new_eq:NN \l_tmpa_box \@tempboxa
\box_new:N \l_tmpb_box
\cs_new_protected_nopar:Npn \vbox:n {\tex_vbox:D \scan_stop:}
+\cs_new_protected_nopar:Npn \vbox_top:n {\tex_vtop:D \scan_stop:}
\cs_new_protected:Npn \vbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_vbox:D {#2}}
\cs_generate_variant:Nn \vbox_set:Nn {cn}
\cs_new_protected_nopar:Npn \vbox_gset:Nn {\pref_global:D \vbox_set:Nn}
\cs_generate_variant:Nn \vbox_gset:Nn {cn}
+\cs_new_protected:Npn \vbox_set_top:Nn #1#2 {\tex_setbox:D #1 \tex_vtop:D {#2}}
+\cs_generate_variant:Nn \vbox_set_top:Nn {cn}
+\cs_new_protected_nopar:Npn \vbox_gset_top:Nn {\pref_global:D \vbox_set_top:Nn}
+\cs_generate_variant:Nn \vbox_gset_top:Nn {cn}
\cs_new_protected:Npn \vbox_set_to_ht:Nnn #1#2#3 {
\tex_setbox:D #1 \tex_vbox:D to #2 {#3}
}
diff --git a/Master/texmf-dist/tex/latex/expl3/l3clist.sty b/Master/texmf-dist/tex/latex/expl3/l3clist.sty
index 17f8ff5f80f..e99dfef6703 100644
--- a/Master/texmf-dist/tex/latex/expl3/l3clist.sty
+++ b/Master/texmf-dist/tex/latex/expl3/l3clist.sty
@@ -48,7 +48,7 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
-\GetIdInfo$Id: l3clist.dtx 1878 2010-03-29 07:15:02Z joseph $
+\GetIdInfo$Id: l3clist.dtx 1992 2010-08-04 20:41:40Z joseph $
{L3 Experimental comma separated lists}
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
@@ -156,48 +156,12 @@
\clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_right:Nn , {}
}
\cs_generate_variant:Nn \clist_gput_right:Nn {NV,No,Nx,cn,cV,co}
-\cs_new_nopar:Npn \clist_map_function:NN #1#2 {
- \clist_if_empty:NF #1 {
- \exp_after:wN \clist_map_function_aux:Nw
- \exp_after:wN #2 #1 , \q_recursion_tail , \q_recursion_stop
- }
-}
-\cs_generate_variant:Nn \clist_map_function:NN {cN}
-\cs_new:Npn \clist_map_function:nN #1#2 {
- \tl_if_blank:nF {#1} {
- \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop
- }
-}
-\cs_new:Npn \clist_map_function_aux:Nw #1#2,{
- \quark_if_recursion_tail_stop:n{#2}
- #1{#2}
- \clist_map_function_aux:Nw #1
-}
-\cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w
-\int_new:N \g_clist_inline_level_int
-\cs_new_protected:Npn \clist_map_inline:Nn #1#2 {
- \clist_if_empty:NF #1 {
- \int_gincr:N \g_clist_inline_level_int
- \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
- ##1{#2}
- \exp_last_unbraced:NcV \clist_map_function_aux:Nw
- {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
- #1 , \q_recursion_tail , \q_recursion_stop
- \int_gdecr:N \g_clist_inline_level_int
- }
-}
-\cs_generate_variant:Nn \clist_map_inline:Nn {c}
-\cs_new_protected:Npn \clist_map_inline:nn #1#2 {
- \tl_if_empty:nF {#1} {
- \int_gincr:N \g_clist_inline_level_int
- \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
- ##1{#2}
- \exp_args:Nc \clist_map_function_aux:Nw
- {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
- #1 , \q_recursion_tail , \q_recursion_stop
- \int_gdecr:N \g_clist_inline_level_int
- }
-}
+\prg_new_map_functions:Nn , { clist }
+\cs_generate_variant:Nn \clist_map_function:NN { Nc }
+\cs_generate_variant:Nn \clist_map_function:NN { c }
+\cs_generate_variant:Nn \clist_map_function:NN { cc }
+\cs_generate_variant:Nn \clist_map_inline:Nn { c }
+\cs_generate_variant:Nn \clist_map_inline:Nn { nc }
\cs_new_protected:Npn \clist_map_variable:nNn #1#2#3 {
\tl_if_empty:nF {#1} {
\clist_map_variable_aux:Nnw #2 {#3} #1
diff --git a/Master/texmf-dist/tex/latex/expl3/l3doc.cls b/Master/texmf-dist/tex/latex/expl3/l3doc.cls
index e747cf92e84..b31d5e6ceb0 100644
--- a/Master/texmf-dist/tex/latex/expl3/l3doc.cls
+++ b/Master/texmf-dist/tex/latex/expl3/l3doc.cls
@@ -53,7 +53,7 @@
\let \filedateOld \filedate
\let \fileversionOld \fileversion
\let \filedescriptionOld \filedescription
-\GetIdInfo$Id: l3doc.dtx 1987 2010-07-25 14:55:46Z joseph $
+\GetIdInfo$Id: l3doc.dtx 2004 2010-08-18 19:39:24Z joseph $
{L3 Experimental documentation class}
\ProvidesExplClass
{\filename}{\filedate}{\fileversion}{\filedescription}
@@ -91,7 +91,7 @@
\ProcessOptions
\LoadClass{article}
\RequirePackage{doc}
-\RequirePackage{array,alphalph,color,fixltx2e,enumitem,textcomp,trace,underscore}
+\RequirePackage{array,alphalph,booktabs,color,fixltx2e,enumitem,textcomp,trace,underscore}
\bool_if:NT \g_doc_lmodern_bool {
\RequirePackage[T1]{fontenc}
\RequirePackage{lmodern}
@@ -100,7 +100,7 @@
\let\doc@verbatim\verbatim
\let\enddoc@verbatim\endverbatim
\let\doc@@verbatim\@verbatim
-\usepackage{verbatim}
+\RequirePackage{verbatim}
\AtBeginDocument{%
\let\verbatim\doc@verbatim
\let\endverbatim\enddoc@verbatim
diff --git a/Master/texmf-dist/tex/latex/expl3/l3expan.sty b/Master/texmf-dist/tex/latex/expl3/l3expan.sty
index 8a356ca0295..ddfce301801 100644
--- a/Master/texmf-dist/tex/latex/expl3/l3expan.sty
+++ b/Master/texmf-dist/tex/latex/expl3/l3expan.sty
@@ -48,7 +48,7 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
-\GetIdInfo$Id: l3expan.dtx 1948 2010-06-10 18:53:09Z joseph $
+\GetIdInfo$Id: l3expan.dtx 1991 2010-08-04 19:49:35Z joseph $
{L3 Experimental Argument Expansion module}
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
diff --git a/Master/texmf-dist/tex/latex/expl3/l3fp.sty b/Master/texmf-dist/tex/latex/expl3/l3fp.sty
index 93915ae18be..8b7f7b67093 100644
--- a/Master/texmf-dist/tex/latex/expl3/l3fp.sty
+++ b/Master/texmf-dist/tex/latex/expl3/l3fp.sty
@@ -48,18 +48,57 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
-\GetIdInfo$Id: l3fp.dtx 1985 2010-07-18 09:05:56Z joseph $
+\GetIdInfo$Id: l3fp.dtx 2021 2010-09-14 15:59:54Z joseph $
{L3 Experimental floating-point operations}
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
\package_check_loaded_expl:
+\int_new:N \c_forty_four
+\int_set:Nn \c_forty_four { 44 }
+\int_new:N \c_one_hundred
+\int_set:Nn \c_one_hundred { 100 }
+\int_new:N \c_one_thousand
+\int_set:Nn \c_one_thousand { 1000 }
+\int_new:N \c_one_million
+\int_set:Nn \c_one_million { 1 000 000 }
+\int_new:N \c_one_hundred_million
+\int_set:Nn \c_one_hundred_million { 100 000 000 }
+\int_new:N \c_five_hundred_million
+\int_set:Nn \c_five_hundred_million { 500 000 000 }
+\int_new:N \c_one_thousand_million
+\int_set:Nn \c_one_thousand_million { 1 000 000 000 }
+\int_new:N \c_fp_pi_by_four_decimal_int
+\int_set:Nn \c_fp_pi_by_four_decimal_int { 785 398 158 }
+\int_new:N \c_fp_pi_by_four_extended_int
+\int_set:Nn \c_fp_pi_by_four_extended_int { 897 448 310 }
+\int_new:N \c_fp_pi_decimal_int
+\int_set:Nn \c_fp_pi_decimal_int { 141 592 653 }
+\int_new:N \c_fp_pi_extended_int
+\int_set:Nn \c_fp_pi_extended_int { 589 793 238 }
+\int_new:N \c_fp_two_pi_decimal_int
+\int_set:Nn \c_fp_two_pi_decimal_int { 283 185 307 }
+\int_new:N \c_fp_two_pi_extended_int
+\int_set:Nn \c_fp_two_pi_extended_int { 179 586 477 }
+\tl_new:N \c_infinity_fp
+\tl_set:Nn \c_infinity_fp { + 2147483647 . 2147483647 e 2147483647 }
+\tl_new:N \c_pi_fp
+\tl_set:Nn \c_pi_fp { + 3.141592654 e 0 }
+\tl_new:N \c_undefined_fp
+\tl_set:Nn \c_undefined_fp { X 0.000000000 e 0 }
+\tl_new:N \c_zero_fp
+\tl_set:Nn \c_zero_fp { + 0.000000000 e 0 }
+\int_new:N \l_fp_count_int
+\int_new:N \l_fp_div_offset_int
+\int_new:N \l_fp_input_a_sign_int
\int_new:N \l_fp_input_a_integer_int
\int_new:N \l_fp_input_a_decimal_int
+\int_new:N \l_fp_input_a_exponent_int
+\int_new:N \l_fp_input_b_sign_int
\int_new:N \l_fp_input_b_integer_int
\int_new:N \l_fp_input_b_decimal_int
-\int_new:N \l_fp_input_a_sign_int
-\int_new:N \l_fp_input_b_sign_int
-\int_new:N \l_fp_split_sign_int
+\int_new:N \l_fp_input_b_exponent_int
+\int_new:N \l_fp_input_a_extended_int
+\int_new:N \l_fp_input_b_extended_int
\int_new:N \l_fp_mul_a_i_int
\int_new:N \l_fp_mul_a_ii_int
\int_new:N \l_fp_mul_a_iii_int
@@ -74,69 +113,227 @@
\int_new:N \l_fp_mul_b_vi_int
\int_new:N \l_fp_mul_output_int
\tl_new:N \l_fp_mul_output_tl
-\int_new:N \l_fp_div_count_int
-\int_new:N \l_fp_div_offset_int
\int_new:N \l_fp_output_sign_int
\int_new:N \l_fp_output_integer_int
\int_new:N \l_fp_output_decimal_int
+\int_new:N \l_fp_output_exponent_int
+\int_new:N \l_fp_output_extended_int
\bool_new:N \l_fp_round_carry_bool
\tl_new:N \l_fp_round_decimal_tl
-\int_new:N \l_fp_round_discard_int
\int_new:N \l_fp_round_position_int
+\int_new:N \l_fp_round_target_int
+\int_new:N \l_fp_split_sign_int
\int_new:N \l_fp_tmp_int
\tl_new:N \l_fp_tmp_tl
-\tl_new:N \c_zero_fp
-\tl_set:Nn \c_zero_fp { + 0.000000000 }
-\tl_new:N \c_undefined_fp
-\tl_set:Nn \c_undefined_fp { X 0.000000000 }
-\tl_new:N \c_infinity_fp
-\tl_set:Nn \c_infinity_fp { +2147483647.2147483647 }
-\tl_new:N \c_minus_infinity_fp
-\tl_set:Nn \c_minus_infinity_fp { -2147483647.2147483647 }
-\int_new:N \c_one_hundred_million
-\int_set:Nn \c_one_hundred_million { 100000000 }
-\int_new:N \c_one_thousand_million
-\int_set:Nn \c_one_thousand_million { 1000000000 }
-\prg_new_conditional:Npnn \fp_if_infinite:N #1 { p , T , F , TF } {
- \tex_ifx:D #1 \c_infinity_fp
- \prg_return_true:
+\tl_new:N \l_fp_trig_arg_tl
+\int_new:N \l_fp_trig_octant_int
+\int_new:N \l_fp_trig_sign_int
+\int_new:N \l_fp_trig_decimal_int
+\int_new:N \l_fp_trig_extended_int
+\cs_new_protected_nopar:Npn \fp_read:N #1 {
+ \exp_after:wN \fp_read_aux:w #1 \q_stop
+}
+\cs_new_protected_nopar:Npn \fp_read_aux:w #1#2 . #3 e #4 \q_stop {
+ \tex_if:D #1 -
+ \l_fp_input_a_sign_int \c_minus_one
\tex_else:D
- \tex_ifx:D #1 \c_minus_infinity_fp
- \prg_return_true:
- \tex_else:D
- \prg_return_false:
- \tex_fi:D
+ \l_fp_input_a_sign_int \c_one
\tex_fi:D
+ \l_fp_input_a_integer_int #2 \scan_stop:
+ \l_fp_input_a_decimal_int #3 \scan_stop:
+ \l_fp_input_a_exponent_int #4 \scan_stop:
}
-\prg_new_conditional:Npnn \fp_if_plus_infinity:N #1 { p , T , F , TF } {
- \tex_ifx:D #1 \c_infinity_fp
- \prg_return_true:
+\cs_new_protected_nopar:Npn \fp_split:Nn #1#2 {
+ \tl_set:Nx \l_fp_tmp_tl {#2}
+ \l_fp_split_sign_int \c_one
+ \fp_split_sign:
+ \use:c { l_fp_input_ #1 _sign_int } \l_fp_split_sign_int
+ \exp_after:wN \fp_split_exponent:w \l_fp_tmp_tl e e \q_stop #1
+}
+\cs_new_protected_nopar:Npn \fp_split_sign: {
+ \tex_ifnum:D \pdf_strcmp:D
+ { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { - }
+ = \c_zero
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN
+ \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
+ }
+ \l_fp_split_sign_int -\l_fp_split_sign_int
+ \exp_after:wN \fp_split_sign:
\tex_else:D
- \prg_return_false:
+ \tex_ifnum:D \pdf_strcmp:D
+ { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { + }
+ = \c_zero
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN
+ \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
+ }
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_split_sign:
+ \tex_fi:D
\tex_fi:D
}
-\prg_new_conditional:Npnn \fp_if_minus_infinity:N #1 { p , T , F , TF }
- {
- \tex_ifx:D #1 \c_minus_infinity_fp
- \prg_return_true:
+\cs_new_protected_nopar:Npn
+ \fp_split_exponent:w #1 e #2 e #3 \q_stop #4 {
+ \use:c { l_fp_input_ #4 _exponent_int }
+ \etex_numexpr:D 0 #2 \scan_stop:
+ \tex_afterassignment:D \fp_split_aux_i:w
+ \use:c { l_fp_input_ #4 _integer_int }
+ \etex_numexpr:D 0 #1 . . \q_stop #4
+}
+\cs_new_protected_nopar:Npn \fp_split_aux_i:w #1 . #2 . #3 \q_stop {
+ \fp_split_aux_ii:w #2 000000000 \q_stop
+}
+\cs_new_protected_nopar:Npn \fp_split_aux_ii:w #1#2#3#4#5#6#7#8#9 {
+ \fp_split_aux_iii:w {#1#2#3#4#5#6#7#8#9}
+}
+\cs_new_protected_nopar:Npn \fp_split_aux_iii:w #1#2 \q_stop {
+ \l_fp_tmp_int 1 #1 \scan_stop:
+ \exp_after:wN \fp_split_decimal:w
+ \int_use:N \l_fp_tmp_int 000000000 \q_stop
+}
+\cs_new_protected_nopar:Npn \fp_split_decimal:w #1#2#3#4#5#6#7#8#9 {
+ \fp_split_decimal_aux:w {#2#3#4#5#6#7#8#9}
+}
+\cs_new_protected_nopar:Npn \fp_split_decimal_aux:w #1#2#3 \q_stop #4 {
+ \use:c { l_fp_input_ #4 _decimal_int } #1#2 \scan_stop:
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \use:c { l_fp_input_ #4 _integer_int } +
+ \use:c { l_fp_input_ #4 _decimal_int }
+ \scan_stop:
+ = \c_zero
+ \use:c { l_fp_input_ #4 _sign_int } \c_one
+ \tex_fi:D
+ \tex_ifnum:D
+ \use:c { l_fp_input_ #4 _integer_int } < \c_one_thousand_million
\tex_else:D
- \prg_return_false:
+ \exp_after:wN \fp_overflow_msg:
\tex_fi:D
}
-\prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF } {
- \tex_ifx:D #1 \c_undefined_fp
- \prg_return_true:
+\cs_new_protected_nopar:Npn \fp_standardise:NNNN #1#2#3#4 {
+ \tex_ifnum:D
+ \etex_numexpr:D #2 + #3 = \c_zero
+ #1 \c_one
+ #4 \c_zero
+ \exp_after:wN \use_none:nnnn
\tex_else:D
- \prg_return_false:
+ \exp_after:wN \fp_standardise_aux:NNNN
\tex_fi:D
+ #1#2#3#4
}
-\prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF } {
- \tex_ifx:D #1 \c_zero_fp
- \prg_return_true:
+\cs_new_protected_nopar:Npn \fp_standardise_aux:NNNN #1#2#3#4 {
+ \cs_set_protected_nopar:Npn \fp_standardise_aux:
+ {
+ \tex_ifnum:D #2 = \c_zero
+ \tex_advance:D #3 \c_one_thousand_million
+ \exp_after:wN \fp_standardise_aux:w
+ \int_use:N #3 \q_stop
+ \exp_after:wN \fp_standardise_aux:
+ \tex_fi:D
+ }
+ \cs_set_protected_nopar:Npn
+ \fp_standardise_aux:w ##1##2##3##4##5##6##7##8##9 \q_stop
+ {
+ #2 ##2 \scan_stop:
+ #3 ##3##4##5##6##7##8##9 0 \scan_stop:
+ \tex_advance:D #4 \c_minus_one
+ }
+ \fp_standardise_aux:
+ \cs_set_protected_nopar:Npn \fp_standardise_aux:
+ {
+ \tex_ifnum:D #2 > \c_nine
+ \tex_advance:D #2 \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_standardise_aux:w \int_use:N #2
+ \exp_after:wN \fp_standardise_aux:
+ \tex_fi:D
+ }
+ \cs_set_protected_nopar:Npn
+ \fp_standardise_aux:w ##1##2##3##4##5##6##7##8##9
+ {
+ #2 ##1##2##3##4##5##6##7##8 \scan_stop:
+ \tex_advance:D #3 \c_one_thousand_million
+ \tex_divide:D #3 \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ ##9
+ \exp_after:wN \use_none:n \int_use:N #3
+ }
+ #3 \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D #4 \c_one
+ }
+ \fp_standardise_aux:
+ \tex_ifnum:D #4 < \c_one_hundred
+ \tex_ifnum:D #4 > -\c_one_hundred
+ \tex_else:D
+ #1 \c_one
+ #2 \c_zero
+ #3 \c_zero
+ #4 \c_zero
+ \tex_fi:D
\tex_else:D
- \prg_return_false:
+ \exp_after:wN \fp_overflow_msg:
\tex_fi:D
}
+\cs_new_protected_nopar:Npn \fp_standardise_aux: { }
+\cs_new_protected_nopar:Npn \fp_standardise_aux:w { }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \exp_after:wN \fp_level_input_exponents_a:
+ \tex_else:D
+ \exp_after:wN \fp_level_input_exponents_b:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_a: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \tex_advance:D \l_fp_input_b_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_level_input_exponents_a:NNNNNNNNN
+ \int_use:N \l_fp_input_b_integer_int
+ \exp_after:wN \fp_level_input_exponents_a:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_level_input_exponents_a:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \l_fp_input_b_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_input_b_decimal_int \c_one_thousand_million
+ \tex_divide:D \l_fp_input_b_decimal_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_b_decimal_int
+ }
+ \l_fp_input_b_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_b_exponent_int \c_one
+}
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_b: {
+ \tex_ifnum:D \l_fp_input_b_exponent_int > \l_fp_input_a_exponent_int
+ \tex_advance:D \l_fp_input_a_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_level_input_exponents_b:NNNNNNNNN
+ \int_use:N \l_fp_input_a_integer_int
+ \exp_after:wN \fp_level_input_exponents_b:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_level_input_exponents_b:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \l_fp_input_a_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \tex_divide:D \l_fp_input_a_decimal_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ }
+ \l_fp_input_a_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+}
+\cs_new_protected_nopar:Npn \fp_tmp:w #1#2 { }
\cs_new_protected_nopar:Npn \fp_new:N #1 {
\tl_new:N #1
\tl_gset_eq:NN #1 \c_zero_fp
@@ -159,21 +356,31 @@
\cs_new_protected_nopar:Npn \fp_set_aux:NNn #1#2#3 {
\group_begin:
\fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
\tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
+ \cs_set_protected_nopar:Npx \fp_tmp:w
{
- \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
- -
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_input_a_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_input_a_decimal_int
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
}
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w
}
\cs_generate_variant:Nn \fp_set:Nn { c }
\cs_generate_variant:Nn \fp_gset:Nn { c }
@@ -185,27 +392,38 @@
}
\cs_new_protected_nopar:Npn \fp_set_from_dim_aux:NNn #1#2#3 {
\group_begin:
- \l_fp_tmp_dim \etex_dimexpr:D #3 \scan_stop:
+ \l_fp_tmp_skip \etex_glueexpr:D #3 \scan_stop:
+ \l_fp_tmp_dim \l_fp_tmp_skip
\fp_split:Nn a
{
\exp_after:wN \fp_set_from_dim_aux:w
\dim_use:N \l_fp_tmp_dim
}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
\tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
+ \cs_set_protected_nopar:Npx \fp_tmp:w
{
- \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
- -
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_input_a_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_input_a_decimal_int
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
}
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w
}
\cs_set_protected_nopar:Npx \fp_set_from_dim_aux:w {
\cs_set_nopar:Npn \exp_not:N \fp_set_from_dim_aux:w
@@ -215,6 +433,7 @@
\cs_generate_variant:Nn \fp_set_from_dim:Nn { c }
\cs_generate_variant:Nn \fp_gset_from_dim:Nn { c }
\dim_new:N \l_fp_tmp_dim
+\skip_new:N \l_fp_tmp_skip
\cs_new_eq:NN \fp_set_eq:NN \tl_set_eq:NN
\cs_new_eq:NN \fp_set_eq:cN \tl_set_eq:cN
\cs_new_eq:NN \fp_set_eq:Nc \tl_set_eq:Nc
@@ -225,101 +444,507 @@
\cs_new_eq:NN \fp_gset_eq:cc \tl_gset_eq:cc
\cs_new_eq:NN \fp_show:N \tl_show:N
\cs_new_eq:NN \fp_show:c \tl_show:c
-\cs_new_eq:NN \fp_use:N \tl_use:N
-\cs_new_eq:NN \fp_use:c \tl_use:c
-\cs_new_protected_nopar:Npn \fp_read:N #1 {
- \exp_after:wN \fp_read_aux:w #1 \q_stop
+\cs_new_nopar:Npn \fp_use:N #1 {
+ \exp_after:wN \fp_use_aux:w #1 \q_stop
}
-\cs_new_protected_nopar:Npn \fp_read_aux:w #1#2 . #3 \q_stop {
+\cs_generate_variant:Nn \fp_use:N { c }
+\cs_new_nopar:Npn \fp_use_aux:w #1#2 e #3 \q_stop {
\tex_if:D #1 -
- \l_fp_input_a_sign_int \c_minus_one
+ -
+ \tex_fi:D
+ \tex_ifnum:D #3 > \c_zero
+ \exp_after:wN \fp_use_large:w
\tex_else:D
- \l_fp_input_a_sign_int \c_one
+ \tex_ifnum:D #3 < \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_use_small:w
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_use_none:w
+ \tex_fi:D
\tex_fi:D
- \l_fp_input_a_integer_int #2 \scan_stop:
- \l_fp_input_a_decimal_int #3 \scan_stop:
+ #2 e #3 \q_stop
}
-\cs_new_protected_nopar:Npn \fp_split:Nn #1#2 {
- \tl_set:Nx \l_fp_tmp_tl {#2}
- \l_fp_split_sign_int \c_one
- \fp_split_sign:
- \use:c { l_fp_input_ #1 _sign_int } \l_fp_split_sign_int
- \tex_afterassignment:D \fp_split_aux_i:w
- \use:c { l_fp_input_ #1 _integer_int }
- \etex_numexpr:D 0 \l_fp_tmp_tl . . \q_stop #1
+\cs_new_nopar:Npn \fp_use_none:w #1 e #2 \q_stop {#1}
+\cs_new_nopar:Npn \fp_use_small:w #1 . #2 e #3 \q_stop {
+ 0 .
+ \prg_replicate:nn { -#3 - 1 } { 0 }
+ #1#2
}
-\cs_new_protected_nopar:Npn \fp_split_sign: {
- \tex_ifnum:D \pdf_strcmp:D
- { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { - }
- = \c_zero
- \tl_set:Nx \l_fp_tmp_tl
- {
- \exp_after:wN
- \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
- }
- \l_fp_split_sign_int -\l_fp_split_sign_int
- \exp_after:wN \fp_split_sign:
+\cs_new_nopar:Npn \fp_use_large:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D #3 < \c_ten
+ \exp_after:wN \fp_use_large_aux_i:w
\tex_else:D
- \tex_ifnum:D \pdf_strcmp:D
- { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_nil } { + }
- = \c_zero
- \tl_set:Nx \l_fp_tmp_tl
- {
- \exp_after:wN
- \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_nil
- }
+ \exp_after:wN \fp_use_large_aux_ii:w
+ \tex_fi:D
+ #1#2 e #3 \q_stop
+}
+\cs_new_nopar:Npn \fp_use_large_aux_i:w #1#2 e #3 \q_stop {
+ #1
+ \use:c { fp_use_large_aux_ #3 :w } #2 \q_stop
+}
+\cs_new_nopar:cpn { fp_use_large_aux_1:w } #1#2 \q_stop { #1 . #2 }
+\cs_new_nopar:cpn { fp_use_large_aux_2:w } #1#2#3 \q_stop {
+ #1#2 . #3
+}
+\cs_new_nopar:cpn { fp_use_large_aux_3:w } #1#2#3#4 \q_stop {
+ #1#2#3 . #4
+}
+\cs_new_nopar:cpn { fp_use_large_aux_4:w } #1#2#3#4#5 \q_stop {
+ #1#2#3#4 . #5
+}
+\cs_new_nopar:cpn { fp_use_large_aux_5:w } #1#2#3#4#5#6 \q_stop {
+ #1#2#3#4#5 . #6
+}
+\cs_new_nopar:cpn { fp_use_large_aux_6:w } #1#2#3#4#5#6#7 \q_stop {
+ #1#2#3#4#5#6 . #7
+}
+\cs_new_nopar:cpn { fp_use_large_aux_7:w } #1#2#3#4#5#6#7#8 \q_stop {
+ #1#2#3#4#6#7 . #8
+}
+\cs_new_nopar:cpn { fp_use_large_aux_8:w } #1#2#3#4#5#6#7#8#9 \q_stop {
+ #1#2#3#4#5#6#7#8 . #9
+}
+\cs_new_nopar:cpn { fp_use_large_aux_9:w } #1 \q_stop { #1 . }
+\cs_new_nopar:Npn \fp_use_large_aux_ii:w #1 e #2 \q_stop {
+ #1
+ \prg_replicate:nn { #2 - 9 } { 0 }
+ .
+}
+\cs_new_nopar:Npn \fp_to_int:N #1 {
+ \exp_after:wN \fp_to_int_aux:w #1 \q_stop
+}
+\cs_generate_variant:Nn \fp_to_int:N { c }
+\cs_new_nopar:Npn \fp_to_int_aux:w #1#2 e #3 \q_stop {
+ \tex_if:D #1 -
+ -
+ \tex_fi:D
+ \tex_ifnum:D #3 < \c_zero
+ \exp_after:wN \fp_to_int_small:w
+ \tex_else:D
+ \exp_after:wN \fp_to_int_large:w
+ \tex_fi:D
+ #2 e #3 \q_stop
+}
+\cs_new_nopar:Npn \fp_to_int_small:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D #3 > \c_one
+ \tex_else:D
+ \tex_ifnum:D #1 < \c_five
+ 0
+ \tex_else:D
+ 1
+ \tex_fi:D
+ \tex_fi:D
+}
+\cs_new_nopar:Npn \fp_to_int_large:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D #3 < \c_ten
+ \exp_after:wN \fp_to_int_large_aux_i:w
+ \tex_else:D
+ \exp_after:wN \fp_to_int_large_aux_ii:w
+ \tex_fi:D
+ #1#2 e #3 \q_stop
+}
+\cs_new_nopar:Npn \fp_to_int_large_aux_i:w #1#2 e #3 \q_stop {
+ \use:c { fp_to_int_large_aux_ #3 :w } #2 \q_stop {#1}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_1:w } #1#2 \q_stop {
+ \fp_to_int_large_aux:nnn { #2 0 } {#1}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_2:w } #1#2#3 \q_stop {
+ \fp_to_int_large_aux:nnn { #3 00 } {#1#2}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_3:w } #1#2#3#4 \q_stop {
+ \fp_to_int_large_aux:nnn { #4 000 } {#1#2#3}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_4:w } #1#2#3#4#5 \q_stop {
+ \fp_to_int_large_aux:nnn { #5 0000 } {#1#2#3#4}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_5:w } #1#2#3#4#5#6 \q_stop {
+ \fp_to_int_large_aux:nnn { #6 00000 } {#1#2#3#4#5}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_6:w } #1#2#3#4#5#6#7 \q_stop {
+ \fp_to_int_large_aux:nnn { #7 000000 } {#1#2#3#4#5#6}
+}
+\cs_new_nopar:cpn
+ { fp_to_int_large_aux_7:w } #1#2#3#4#5#6#7#8 \q_stop {
+ \fp_to_int_large_aux:nnn { #8 0000000 } {#1#2#3#4#5#6#7}
+}
+\cs_new_nopar:cpn
+ { fp_to_int_large_aux_8:w } #1#2#3#4#5#6#7#8#9 \q_stop {
+ \fp_to_int_large_aux:nnn { #9 00000000 } {#1#2#3#4#5#6#7#8}
+}
+\cs_new_nopar:cpn { fp_to_int_large_aux_9:w } #1 \q_stop {#1}
+\cs_new_nopar:Npn \fp_to_int_large_aux:nnn #1#2#3 {
+ \tex_ifnum:D #1 < \c_five_hundred_million
+ #3#2
+ \tex_else:D
+ \tex_number:D \etex_numexpr:D #3#2 + 1 \scan_stop:
+ \tex_fi:D
+}
+\cs_new_nopar:Npn \fp_to_int_large_aux_ii:w #1 e #2 \q_stop {
+ #1
+ \prg_replicate:nn { #2 - 9 } { 0 }
+}
+\cs_new_nopar:Npn \fp_to_tl:N #1 {
+ \exp_after:wN \fp_to_tl_aux:w #1 \q_stop
+}
+\cs_generate_variant:Nn \fp_to_tl:N { c }
+\cs_new_nopar:Npn \fp_to_tl_aux:w #1#2 e #3 \q_stop {
+ \tex_if:D #1 -
+ -
+ \tex_fi:D
+ \tex_ifnum:D #3 < \c_zero
+ \exp_after:wN \fp_to_tl_small:w
+ \tex_else:D
+ \exp_after:wN \fp_to_tl_large:w
+ \tex_fi:D
+ #2 e #3 \q_stop
+}
+\cs_new_nopar:Npn \fp_to_tl_large:w #1 e #2 \q_stop {
+ \tex_ifnum:D #2 < \c_ten
+ \exp_after:wN \fp_to_tl_large_aux_i:w
+ \tex_else:D
+ \exp_after:wN \fp_to_tl_large_aux_ii:w
+ \tex_fi:D
+ #1 e #2 \q_stop
+}
+\cs_new_nopar:Npn \fp_to_tl_large_aux_i:w #1 e #2 \q_stop {
+ \use:c { fp_to_tl_large_ #2 :w } #1 \q_stop
+}
+\cs_new_nopar:Npn \fp_to_tl_large_aux_ii:w #1 . #2 e #3 \q_stop {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ e #3
+}
+\cs_new_nopar:cpn { fp_to_tl_large_0:w } #1 . #2 \q_stop {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+}
+\cs_new_nopar:cpn { fp_to_tl_large_1:w } #1 . #2#3 \q_stop {
+ #1#2
+ \fp_to_tl_large_zeros:NNNNNNNNN #3 0
+}
+\cs_new_nopar:cpn { fp_to_tl_large_2:w } #1 . #2#3#4 \q_stop {
+ #1#2#3
+ \fp_to_tl_large_zeros:NNNNNNNNN #4 00
+}
+\cs_new_nopar:cpn { fp_to_tl_large_3:w } #1 . #2#3#4#5 \q_stop {
+ #1#2#3#4
+ \fp_to_tl_large_zeros:NNNNNNNNN #5 000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_4:w } #1 . #2#3#4#5#6 \q_stop {
+ #1#2#3#4#5
+ \fp_to_tl_large_zeros:NNNNNNNNN #6 0000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_5:w } #1 . #2#3#4#5#6#7 \q_stop {
+ #1#2#3#4#5#6
+ \fp_to_tl_large_zeros:NNNNNNNNN #7 00000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_6:w } #1 . #2#3#4#5#6#7#8 \q_stop {
+ #1#2#3#4#5#6#7
+ \fp_to_tl_large_zeros:NNNNNNNNN #8 000000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_7:w } #1 . #2#3#4#5#6#7#8#9 \q_stop {
+ #1#2#3#4#5#6#7#8
+ \fp_to_tl_large_zeros:NNNNNNNNN #9 0000000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_8:w } #1 . {
+ #1
+ \use:c { fp_to_tl_large_8_aux:w }
+}
+\cs_new_nopar:cpn
+ { fp_to_tl_large_8_aux:w } #1#2#3#4#5#6#7#8#9 \q_stop {
+ #1#2#3#4#5#6#7#8
+ \fp_to_tl_large_zeros:NNNNNNNNN #9 00000000
+}
+\cs_new_nopar:cpn { fp_to_tl_large_9:w } #1 . #2 \q_stop {#1#2}
+\cs_new_nopar:Npn \fp_to_tl_small:w #1 e #2 \q_stop {
+ \tex_ifnum:D #2 = \c_minus_one
+ \exp_after:wN \fp_to_tl_small_one:w
+ \tex_else:D
+ \tex_ifnum:D #2 = -\c_two
\exp_after:wN \exp_after:wN \exp_after:wN
- \fp_split_sign:
- \tex_fi:D
+ \fp_to_tl_small_two:w
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_to_tl_small_aux:w
+ \tex_fi:D
\tex_fi:D
+ #1 e #2 \q_stop
}
-\cs_new_protected_nopar:Npn \fp_split_aux_i:w #1 . #2 . #3 \q_stop {
- \fp_split_aux_ii:w #2 000000000 \q_stop
+\cs_new_nopar:Npn \fp_to_tl_small_one:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D \fp_use_ix:NNNNNNNNN #2 > \c_four
+ \tex_ifnum:D
+ \etex_numexpr:D #1 \fp_use_i_to_iix:NNNNNNNNN #2 + 1
+ < \c_one_thousand_million
+ 0.
+ \exp_after:wN \fp_to_tl_small_zeros:NNNNNNNNN
+ \tex_number:D
+ \etex_numexpr:D
+ #1 \fp_use_i_to_iix:NNNNNNNNN #2 + 1
+ \scan_stop:
+ \tex_else:D
+ 1
+ \tex_fi:D
+ \tex_else:D
+ 0. #1
+ \fp_to_tl_small_zeros:NNNNNNNNN #2
+ \tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_split_aux_ii:w #1#2#3#4#5#6#7#8#9 {
- \fp_split_aux_iii:w {#1#2#3#4#5#6#7#8#9}
+\cs_new_nopar:Npn \fp_to_tl_small_two:w #1 . #2 e #3 \q_stop {
+ \tex_ifnum:D \fp_use_iix_ix:NNNNNNNNN #2 > \c_forty_four
+ \tex_ifnum:D
+ \etex_numexpr:D #1 \fp_use_i_to_vii:NNNNNNNNN #2 0 + \c_ten
+ < \c_one_thousand_million
+ 0.0
+ \exp_after:wN \fp_to_tl_small_zeros:NNNNNNNNN
+ \tex_number:D
+ \etex_numexpr:D
+ #1 \fp_use_i_to_vii:NNNNNNNNN #2 0 + \c_ten
+ \scan_stop:
+ \tex_else:D
+ 0.1
+ \tex_fi:D
+ \tex_else:D
+ 0.0
+ #1
+ \fp_to_tl_small_zeros:NNNNNNNNN #2
+ \tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_split_aux_iii:w #1#2 \q_stop {
- \l_fp_tmp_int 1 #1 \scan_stop:
- \exp_after:wN \fp_split_decimal:w
- \int_use:N \l_fp_tmp_int 000000000 \q_stop
+\cs_new_nopar:Npn \fp_to_tl_small_aux:w #1 . #2 e #3 \q_stop {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ e #3
+}
+\cs_new_nopar:Npn \fp_to_tl_large_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \tex_ifnum:D #9 = \c_zero
+ \tex_ifnum:D #8 = \c_zero
+ \tex_ifnum:D #7 = \c_zero
+ \tex_ifnum:D #6 = \c_zero
+ \tex_ifnum:D #5 = \c_zero
+ \tex_ifnum:D #4 = \c_zero
+ \tex_ifnum:D #3 = \c_zero
+ \tex_ifnum:D #2 = \c_zero
+ \tex_ifnum:D #1 = \c_zero
+ \tex_else:D
+ . #1
+ \tex_fi:D
+ \tex_else:D
+ . #1#2
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5#6
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5#6#7
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5#6#7#8
+ \tex_fi:D
+ \tex_else:D
+ . #1#2#3#4#5#6#7#8#9
+ \tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_split_decimal:w #1#2#3#4#5#6#7#8#9 {
- \fp_split_decimal_aux:w {#2#3#4#5#6#7#8#9}
+\cs_new_nopar:Npn \fp_to_tl_small_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \tex_ifnum:D #9 = \c_zero
+ \tex_ifnum:D #8 = \c_zero
+ \tex_ifnum:D #7 = \c_zero
+ \tex_ifnum:D #6 = \c_zero
+ \tex_ifnum:D #5 = \c_zero
+ \tex_ifnum:D #4 = \c_zero
+ \tex_ifnum:D #3 = \c_zero
+ \tex_ifnum:D #2 = \c_zero
+ \tex_ifnum:D #1 = \c_zero
+ \tex_else:D
+ #1
+ \tex_fi:D
+ \tex_else:D
+ #1#2
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5#6
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5#6#7
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5#6#7#8
+ \tex_fi:D
+ \tex_else:D
+ #1#2#3#4#5#6#7#8#9
+ \tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_split_decimal_aux:w #1#2#3 \q_stop #4 {
- \use:c { l_fp_input_ #4 _decimal_int } #1#2 \scan_stop:
- \tex_ifnum:D
- \etex_numexpr:D
- \use:c { l_fp_input_ #4 _integer_int } +
- \use:c { l_fp_input_ #4 _decimal_int }
- \scan_stop:
- = \c_zero
- \use:c { l_fp_input_ #4 _sign_int } \c_one
- \tex_fi:D
+\cs_new_nopar:Npn \fp_use_iix_ix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {#8#9}
+\cs_new_nopar:Npn \fp_use_ix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {#9}
+\cs_new_nopar:Npn \fp_use_i_to_vii:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ #1#2#3#4#5#6#7
+}
+\cs_new_nopar:Npn \fp_use_i_to_iix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ #1#2#3#4#5#6#7#8
+}
+\cs_new_protected_nopar:Npn \fp_round_figures:Nn {
+ \fp_round_figures_aux:NNn \tl_set:Nn
+}
+\cs_generate_variant:Nn \fp_round_figures:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ground_figures:Nn {
+ \fp_round_figures_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_ground_figures:Nn { c }
+\cs_new_protected_nopar:Npn \fp_round_figures_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_read:N #2
+ \int_set:Nn \l_fp_round_target_int { #3 - 1 }
+ \tex_ifnum:D \l_fp_round_target_int < \c_ten
+ \exp_after:wN \fp_round:
+ \tex_fi:D
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+}
+\cs_new_protected_nopar:Npn \fp_round_places:Nn {
+ \fp_round_places_aux:NNn \tl_set:Nn
+}
+\cs_generate_variant:Nn \fp_round_places:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ground_places:Nn {
+ \fp_round_places_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_ground_places:Nn { c }
+\cs_new_protected_nopar:Npn \fp_round_places_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_read:N #2
+ \int_set:Nn \l_fp_round_target_int
+ { #3 + \l_fp_input_a_exponent_int }
+ \tex_ifnum:D \l_fp_round_target_int < \c_ten
+ \exp_after:wN \fp_round:
+ \tex_fi:D
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+}
+\cs_new_protected_nopar:Npn \fp_round: {
+ \bool_set_false:N \l_fp_round_carry_bool
+ \l_fp_round_position_int \c_eight
+ \tl_clear:N \l_fp_round_decimal_tl
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_round_aux:NNNNNNNNN \int_use:N \l_fp_input_a_decimal_int
+}
+\cs_new_protected_nopar:Npn \fp_round_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \fp_round_loop:N #9#8#7#6#5#4#3#2#1
+ \bool_if:NT \l_fp_round_carry_bool
+ { \tex_advance:D \l_fp_input_a_integer_int \c_one }
+ \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
+ \tex_ifnum:D \l_fp_input_a_integer_int < \c_ten
+ \tex_else:D
+ \l_fp_input_a_integer_int \c_one
+ \tex_divide:D \l_fp_input_a_decimal_int \c_ten
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_round_loop:N #1 {
+ \tex_ifnum:D \l_fp_round_position_int < \l_fp_round_target_int
+ \bool_if:NTF \l_fp_round_carry_bool
+ { \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop: }
+ { \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop: }
+ \tex_ifnum:D \l_fp_tmp_int = \c_ten
+ \l_fp_tmp_int \c_zero
+ \tex_else:D
+ \bool_set_false:N \l_fp_round_carry_bool
+ \tex_fi:D
+ \tl_set:Nx \l_fp_round_decimal_tl
+ { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
+ \tex_else:D
+ \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
+ \tex_ifnum:D \l_fp_round_position_int = \l_fp_round_target_int
+ \tex_ifnum:D #1 > \c_four
+ \bool_set_true:N \l_fp_round_carry_bool
+ \tex_fi:D
+ \tex_fi:D
+ \tex_fi:D
+ \tex_advance:D \l_fp_round_position_int \c_minus_one
+ \tex_ifnum:D \l_fp_round_position_int > \c_minus_one
+ \exp_after:wN \fp_round_loop:N
+ \tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_abs:N {
- \fp_abs:NN \tl_set:Nn
+ \fp_abs_aux:NN \tl_set:Nn
}
\cs_new_protected_nopar:Npn \fp_gabs:N {
- \fp_abs:NN \tl_gset:Nn
+ \fp_abs_aux:NN \tl_gset:Nn
}
\cs_generate_variant:Nn \fp_abs:N { c }
\cs_generate_variant:Nn \fp_gabs:N { c }
-\cs_new_protected_nopar:Npn \fp_abs:NN #1#2 {
+\cs_new_protected_nopar:Npn \fp_abs_aux:NN #1#2 {
\group_begin:
\fp_read:N #2
\tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
+ \cs_set_protected_nopar:Npx \fp_tmp:w
{
- +
- \int_use:N \l_fp_input_a_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_input_a_decimal_int
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ +
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
}
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w
}
\cs_new_protected_nopar:Npn \fp_neg:N {
\fp_neg_aux:NN \tl_set:Nn
@@ -344,6 +969,8 @@
.
\exp_after:wN \use_none:n
\int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
}
\exp_after:wN \group_end: \exp_after:wN
#1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
@@ -360,11 +987,16 @@
\group_begin:
\fp_read:N #2
\fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
\fp_add_core:
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w #1#2
}
\cs_new_protected_nopar:Npn \fp_add_core: {
+ \fp_level_input_exponents:
\tex_ifnum:D
\etex_numexpr:D
\l_fp_input_a_sign_int * \l_fp_input_b_sign_int
@@ -374,17 +1006,30 @@
\tex_else:D
\exp_after:wN \fp_add_difference:
\tex_fi:D
- \tl_set:Nx \l_fp_tmp_tl
+ \l_fp_output_exponent_int \l_fp_input_a_exponent_int
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
{
- \tex_ifnum:D \l_fp_output_sign_int < \c_zero
- -
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_output_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_output_decimal_int
+ \group_end:
+ ##1 ##2
+ {
+ \tex_ifnum:D \l_fp_output_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
}
}
\cs_new_protected_nopar:Npn \fp_add_sum: {
@@ -398,9 +1043,9 @@
\l_fp_input_a_decimal_int + \l_fp_input_b_decimal_int
\scan_stop:
\tex_ifnum:D \l_fp_output_decimal_int < \c_one_thousand_million
- \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
\tex_else:D
\tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int -\c_one_thousand_million
\tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_add_difference: {
@@ -433,14 +1078,6 @@
\tex_else:D
\l_fp_output_sign_int \l_fp_input_a_sign_int
\tex_fi:D
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_output_integer_int + \l_fp_output_decimal_int
- \scan_stop:
- = \c_zero
- \l_fp_output_sign_int \c_one
- \tex_fi:D
- \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
}
\cs_new_protected_nopar:Npn \fp_sub:Nn {
\fp_sub_aux:NNn \tl_set:Nn
@@ -454,10 +1091,14 @@
\group_begin:
\fp_read:N #2
\fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
\tex_multiply:D \l_fp_input_b_sign_int \c_minus_one
\fp_add_core:
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w #1#2
}
\cs_new_protected_nopar:Npn \fp_mul:Nn {
\fp_mul_aux:NNn \tl_set:Nn
@@ -471,93 +1112,80 @@
\group_begin:
\fp_read:N #2
\fp_split:Nn b {#3}
- \fp_mul_split:NNNN \l_fp_input_a_integer_int
- \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
- \fp_mul_split:NNNN \l_fp_input_a_decimal_int
- \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
- \fp_mul_split:NNNN \l_fp_input_b_integer_int
- \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
- \fp_mul_split:NNNN \l_fp_input_b_decimal_int
- \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
- \l_fp_mul_output_int \c_zero
- \tl_clear:N \l_fp_mul_output_tl
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_vi_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_iv_int
- \tex_divide:D \l_fp_mul_output_int \c_thousand
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_vi_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_iii_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_vi_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_ii_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_vi_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \l_fp_output_decimal_int 0 \l_fp_mul_output_tl \scan_stop:
- \tl_clear:N \l_fp_mul_output_tl
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_v_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iv_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \l_fp_output_integer_int 0 \l_fp_mul_output_tl \scan_stop:
- \tl_clear:N \l_fp_mul_output_tl
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
- \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
- \fp_mul_end_level:
- \tex_ifnum:D \l_fp_mul_output_tl = \c_zero
- \tex_else:D
- \exp_after:wN \fp_msg_overflow:
- \tex_fi:D
- \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_mul_int:
+ \l_fp_output_exponent_int
+ \etex_numexpr:D
+ \l_fp_input_a_exponent_int + \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w
{
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
- \scan_stop:
- < \c_zero
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_output_integer_int + \l_fp_output_decimal_int
- \scan_stop:
- = \c_one_thousand_million
- +
- \tex_else:D
- -
- \tex_fi:D
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_output_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_output_decimal_int
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ < \c_zero
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_output_integer_int + \l_fp_output_decimal_int
+ = \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
}
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w
+}
+\cs_new_protected_nopar:Npn \fp_mul_int: {
+ \fp_mul_split:NNNN \l_fp_input_a_decimal_int
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN \l_fp_input_b_decimal_int
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \l_fp_output_decimal_int 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \l_fp_output_integer_int 0 \l_fp_mul_output_tl \scan_stop:
}
\cs_new_protected_nopar:Npn \fp_mul_split:NNNN #1#2#3#4 {
\tex_advance:D #1 \c_one_thousand_million
@@ -568,6 +1196,7 @@
#4 ##8##9 \scan_stop:
}
\exp_after:wN \fp_mul_split_aux:w \int_use:N #1 \q_stop
+ \tex_advance:D #1 -\c_one_thousand_million
}
\cs_new_protected_nopar:Npn \fp_mul_product:NN #1#2 {
\l_fp_mul_output_int
@@ -575,13 +1204,13 @@
}
\cs_new_protected_nopar:Npn \fp_mul_end_level: {
\tex_advance:D \l_fp_mul_output_int \c_one_thousand_million
- \exp_after:wN \fp_mul_end_level:w
- \int_use:N \l_fp_mul_output_int \q_stop
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_mul_end_level:NNNNNNNNN \int_use:N \l_fp_mul_output_int
}
-\cs_new_protected_nopar:Npn \fp_mul_end_level:w
- #1#2#3#4#5#6#7#8#9 \q_stop {
- \tl_set:Nx \l_fp_mul_output_tl { #8#9 \l_fp_mul_output_tl }
- \l_fp_mul_output_int #5#6#7 \scan_stop:
+\cs_new_protected_nopar:Npn \fp_mul_end_level:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9 {
+ \tl_set:Nx \l_fp_mul_output_tl { #7#8#9 \l_fp_mul_output_tl }
+ \l_fp_mul_output_int #1#2#3#4#5#6 \scan_stop:
}
\cs_new_protected_nopar:Npn \fp_div:Nn {
\fp_div_aux:NNn \tl_set:Nn
@@ -596,94 +1225,99 @@
\group_begin:
\fp_read:N #2
\fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
\tex_ifnum:D
\etex_numexpr:D
\l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
- \scan_stop:
= \c_zero
- \tl_set_eq:NN \l_fp_tmp_tl \c_undefined_fp
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \c_undefined_fp }
+ }
\tex_else:D
\tex_ifnum:D
\etex_numexpr:D
\l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
- \scan_stop:
= \c_zero
- \tl_set_eq:NN \l_fp_tmp_tl \c_zero_fp
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \c_zero_fp }
+ }
\tex_else:D
\exp_after:wN \exp_after:wN \exp_after:wN
\fp_div_aux:
\tex_fi:D
\tex_fi:D
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ \fp_tmp:w #1#2
}
\cs_new_protected_nopar:Npn \fp_div_aux: {
- \l_fp_div_offset_int \c_one
- \tex_ifnum:D \l_fp_input_a_integer_int > \c_zero
- \exp_after:wN \fp_div_offset_create:
- \tex_fi:D
\l_fp_output_integer_int \c_zero
- \l_fp_output_decimal_int \c_one_thousand_million
+ \l_fp_output_decimal_int \c_zero
\cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
+ \l_fp_div_offset_int \c_one_hundred_million
\fp_div_loop:
- \tl_set:Nx \l_fp_tmp_tl
+ \l_fp_output_exponent_int
+ \etex_numexpr:D
+ \l_fp_input_a_exponent_int - \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
{
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
- \scan_stop:
- < \c_zero
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_output_integer_int + \l_fp_output_decimal_int
- \scan_stop:
- = \c_one_thousand_million
- +
- \tex_else:D
- -
- \tex_fi:D
- \tex_else:D
- +
- \tex_fi:D
- \int_use:N \l_fp_output_integer_int
- .
- \exp_after:wN \use_none:n
- \int_use:N \l_fp_output_decimal_int
+ \group_end:
+ ##1 ##2
+ {
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ < \c_zero
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_output_integer_int + \l_fp_output_decimal_int
+ = \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
}
}
-\cs_new_protected_nopar:Npn \fp_div_offset_create: {
- \tex_ifnum:D \l_fp_input_b_integer_int = \c_zero
- \tex_advance:D \l_fp_input_b_decimal_int \c_one_thousand_million
- \exp_after:wN \fp_div_offset_create_aux:w
- \int_use:N \l_fp_input_b_decimal_int \q_stop
- \exp_after:wN \fp_div_offset_create:
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_div_offset_create_aux:w
- #1#2#3#4#5#6#7#8#9 \q_stop {
- \l_fp_input_b_integer_int #2 \scan_stop:
- \l_fp_input_b_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
- \tex_multiply:D \l_fp_div_offset_int \c_ten
-}
\cs_new_protected_nopar:Npn \fp_div_loop: {
- \l_fp_div_count_int \c_zero
+ \l_fp_count_int \c_zero
\fp_div_divide:
- \tex_divide:D \l_fp_input_b_decimal_int \c_ten
- \tex_advance:D \l_fp_input_b_integer_int \c_one_thousand_million
- \exp_after:wN \fp_div_loop_aux_i:w
- \int_use:N \l_fp_input_b_integer_int
\fp_div_store:
+ \tex_multiply:D \l_fp_input_a_integer_int \c_ten
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \fp_div_loop_step:w
+ \int_use:N \l_fp_input_a_decimal_int \q_stop
\tex_ifnum:D
\etex_numexpr:D
\l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
> \c_zero
- \tex_ifnum:D
- \etex_numexpr:D
- \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
- > \c_zero
- \exp_after:wN \exp_after:wN \exp_after:wN
- \fp_div_loop:
- \tex_fi:D
+ \tex_ifnum:D \l_fp_div_offset_int > \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_div_loop:
+ \tex_fi:D
\tex_fi:D
}
\cs_new_protected_nopar:Npn \fp_div_divide: {
@@ -702,18 +1336,8 @@
\tex_fi:D
\tex_fi:D
}
-\cs_new_protected_nopar:Npn \fp_div_loop_aux_i:w #1#2#3#4#5#6#7#8#9 {
- \fp_div_loop_aux_ii:w #2#3#4#5#6#7#8#9
-}
-\cs_new_protected_nopar:Npn \fp_div_loop_aux_ii:w #1#2#3#4#5#6#7#8#9 {
- \l_fp_input_b_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
- \l_fp_input_b_decimal_int
- \etex_numexpr:D
- \l_fp_input_b_decimal_int + \c_one_hundred_million * #9
- \scan_stop:
-}
\cs_new_protected_nopar:Npn \fp_div_divide_aux: {
- \tex_advance:D \l_fp_div_count_int \c_one
+ \tex_advance:D \l_fp_count_int \c_one
\tex_advance:D \l_fp_input_a_integer_int -\l_fp_input_b_integer_int
\tex_advance:D \l_fp_input_a_decimal_int -\l_fp_input_b_decimal_int
\tex_ifnum:D \l_fp_input_a_decimal_int < \c_zero
@@ -724,40 +1348,745 @@
}
\cs_new_protected_nopar:Npn \fp_div_store: { }
\cs_new_protected_nopar:Npn \fp_div_store_integer: {
- \l_fp_output_integer_int
- \etex_numexpr:D
- \l_fp_output_integer_int +
- \l_fp_div_count_int * \l_fp_div_offset_int
- \scan_stop:
- \tex_ifnum:D \l_fp_div_offset_int > \c_one
- \tex_divide:D \l_fp_div_offset_int \c_ten
- \tex_else:D
- \cs_set_eq:NN \fp_div_store: \fp_div_store_decimal:
- \l_fp_div_offset_int \c_one_hundred_million
- \tex_fi:D
+ \l_fp_output_integer_int \l_fp_count_int
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_decimal:
}
\cs_new_protected_nopar:Npn \fp_div_store_decimal: {
\l_fp_output_decimal_int
\etex_numexpr:D
\l_fp_output_decimal_int +
- \l_fp_div_count_int * \l_fp_div_offset_int
+ \l_fp_count_int * \l_fp_div_offset_int
\scan_stop:
\tex_divide:D \l_fp_div_offset_int \c_ten
}
-\prg_new_protected_conditional:Npnn \fp_compare:nNn #1#2#3
- { T , F , TF } {
+\cs_new_protected_nopar:Npn
+ \fp_div_loop_step:w #1#2#3#4#5#6#7#8#9 \q_stop {
+ \l_fp_input_a_integer_int
+ \etex_numexpr:D
+ #2 + \l_fp_input_a_integer_int
+ \scan_stop:
+ \l_fp_input_a_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
+}
+\cs_new_protected_nopar:Npn \fp_add:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ #7 \etex_numexpr:D #1 + #4 \scan_stop:
+ #8 \etex_numexpr:D #2 + #5 \scan_stop:
+ #9 \etex_numexpr:D #3 + #6 \scan_stop:
+ \tex_ifnum:D #9 < \c_one_thousand_million
+ \tex_else:D
+ \tex_advance:D #8 \c_one
+ \tex_advance:D #9 -\c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D #8 < \c_one_thousand_million
+ \tex_else:D
+ \tex_advance:D #7 \c_one
+ \tex_advance:D #8 -\c_one_thousand_million
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_sub:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ #7 \etex_numexpr:D #1 - #4 \scan_stop:
+ #8 \etex_numexpr:D #2 - #5 \scan_stop:
+ #9 \etex_numexpr:D #3 - #6 \scan_stop:
+ \tex_ifnum:D #9 < \c_zero
+ \tex_advance:D #8 \c_minus_one
+ \tex_advance:D #9 \c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D #8 < \c_zero
+ \tex_advance:D #7 \c_minus_one
+ \tex_advance:D #8 \c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D #7 < \c_zero
+ \tex_ifnum:D \etex_numexpr:D #8 + #9 = \c_zero
+ #7 -#7
+ \tex_else:D
+ \tex_advance:D #7 \c_one
+ #8 \etex_numexpr:D \c_one_thousand_million - #8 \scan_stop:
+ #9 \etex_numexpr:D \c_one_thousand_million - #9 \scan_stop:
+ \tex_fi:D
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_mul:NNNNNN #1#2#3#4#5#6 {
+ \fp_mul_split:NNNN #1
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN #2
+ \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
+ \fp_mul_split:NNNN #3
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_split:NNNN #4
+ \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_vi_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_ii_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ #6 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_end_level:
+ #5 0 \l_fp_mul_output_tl \scan_stop:
+}
+\cs_new_protected_nopar:Npn \fp_div_integer:NNNNN #1#2#3#4#5 {
+ \l_fp_tmp_int #1
+ \tex_divide:D \l_fp_tmp_int #3
+ \l_fp_tmp_int \etex_numexpr:D #1 - \l_fp_tmp_int * #3 \scan_stop:
+ #4 #1
+ \tex_divide:D #4 #3
+ #5 #2
+ \tex_divide:D #5 #3
+ \tex_multiply:D \l_fp_tmp_int \c_one_thousand
+ \tex_divide:D \l_fp_tmp_int #3
+ #5 \etex_numexpr:D #5 + \l_fp_tmp_int * \c_one_million \scan_stop:
+ \tex_ifnum:D #5 > \c_one_thousand_million
+ \tex_advance:D #4 \c_one
+ \tex_advancd:D #5 -\c_one_thousand_million
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_normalise: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int < \c_ten
+ \l_fp_input_a_extended_int \c_zero
+ \fp_trig_normalise_aux_i:
+ \fp_trig_normalise_aux_ii:
+ \fp_trig_normalise_aux_iii:
+ \tex_ifnum:D \l_fp_input_a_integer_int < \c_zero
+ \l_fp_input_a_sign_int -\l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int -\l_fp_input_a_integer_int
+ \tex_fi:D
+ \exp_after:wN \fp_trig_octant:
+ \tex_else:D
+ \l_fp_input_a_sign_int \c_one
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \exp_after:wN \fp_trig_overflow_msg:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_normalise_aux_i: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int > \c_zero
+ \tex_multiply:D \l_fp_input_a_integer_int \c_ten
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \fp_trig_normalise_aux:w
+ \int_use:N \l_fp_input_a_decimal_int \q_stop
+ \exp_after:wN \fp_trig_normalise_aux_i:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_trig_normalise_aux:w #1#2#3#4#5#6#7#8#9 \q_stop {
+ \l_fp_input_a_integer_int
+ \etex_numexpr:D \l_fp_input_a_integer_int + #2 \scan_stop:
+ \l_fp_input_a_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_minus_one
+}
+\cs_new_protected_nopar:Npn \fp_trig_normalise_aux_ii: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int < \c_zero
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_trig_normalise_aux:NNNNNNNNN
+ \int_use:N \l_fp_input_a_decimal_int
+ \exp_after:wN \fp_trig_normalise_aux_ii:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn
+ \fp_trig_normalise_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
+ \tex_ifnum:D \l_fp_input_a_integer_int = \c_zero
+ \l_fp_input_a_decimal_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_else:D
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_use:N \l_fp_input_a_integer_int
+ #1#2#3#4#5#6#7#8
+ }
+ \l_fp_input_a_integer_int \c_zero
+ \l_fp_input_a_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_fi:D
+ \tex_divide:D \l_fp_input_a_extended_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \int_use:N \l_fp_input_a_extended_int
+ }
+ \l_fp_input_a_extended_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+}
+\cs_new_protected_nopar:Npn \fp_trig_normalise_aux_iii: {
+ \tex_ifnum:D \l_fp_input_a_integer_int > \c_three
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_six \c_fp_two_pi_decimal_int \c_fp_two_pi_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \exp_after:wN \fp_trig_normalise_aux_iii:
+ \tex_else:D
+ \tex_ifnum:D \l_fp_input_a_integer_int > \c_two
+ \tex_ifnum:D \l_fp_input_a_decimal_int > \c_fp_pi_decimal_int
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_six \c_fp_two_pi_decimal_int \c_fp_two_pi_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_trig_normalise_aux_iii:
+ \tex_fi:D
+ \tex_fi:D
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_octant: {
+ \l_fp_trig_octant_int \c_one
+ \fp_trig_octant_aux:
+ \tex_ifnum:D \l_fp_input_a_decimal_int < \c_ten
+ \l_fp_input_a_decimal_int \c_zero
+ \l_fp_input_a_extended_int \c_zero
+ \tex_fi:D
+ \tex_ifodd:D \l_fp_trig_octant_int
+ \tex_else:D
+ \fp_sub:NNNNNNNNN
+ \c_zero \c_fp_pi_by_four_decimal_int \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_octant_aux: {
+ \tex_ifnum:D \l_fp_input_a_integer_int > \c_zero
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_zero \c_fp_pi_by_four_decimal_int \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_advance:D \l_fp_trig_octant_int \c_one
+ \exp_after:wN \fp_trig_octant_aux:
+ \tex_else:D
+ \tex_ifnum:D
+ \l_fp_input_a_decimal_int > \c_fp_pi_by_four_decimal_int
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_zero \c_fp_pi_by_four_decimal_int
+ \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_advance:D \l_fp_trig_octant_int \c_one
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_trig_octant_aux:
+ \tex_fi:D
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_sin:Nn {
+ \fp_sin_aux:NNn \tl_set:Nn
+}
+\cs_new_protected_nopar:Npn \fp_gsin:Nn {
+ \fp_sin_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_sin:Nn { c }
+\cs_generate_variant:Nn \fp_gsin:Nn { c }
+\cs_new_protected_nopar:Npn \fp_sin_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_trig_arg_tl
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \tex_ifnum:D \l_fp_input_a_exponent_int < -\c_five
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \l_fp_trig_arg_tl }
+ }
+ \tex_else:D
+ \etex_ifcsname:D
+ c_fp_sin ( \l_fp_trig_arg_tl ) _tl
+ \tex_endcsname:D
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_sin_aux_i:
+ \tex_fi:D
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_sin ( \l_fp_trig_arg_tl ) _tl } }
+ }
+ \tex_fi:D
+ \fp_tmp:w
+}
+\cs_new_protected_nopar:Npn \fp_sin_aux_i: {
+ \fp_trig_normalise:
+ \fp_sin_aux_ii:
+ \tex_ifnum:D \l_fp_output_integer_int = \c_one
+ \l_fp_output_exponent_int \c_zero
+ \tex_else:D
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_decimal_int \l_fp_output_extended_int
+ \l_fp_output_exponent_int -\c_nine
+ \tex_fi:D
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_sin ( \l_fp_trig_arg_tl ) _tl }
+ \tl_set:cx { c_fp_sin ( \l_fp_trig_arg_tl ) _tl }
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int > \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+}
+\cs_new_protected_nopar:Npn \fp_sin_aux_ii: {
+ \tex_ifcase:D \l_fp_trig_octant_int
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_sin:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_cos:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_cos:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_sin:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_cos:Nn {
+ \fp_cos_aux:NNn \tl_set:Nn
+}
+\cs_new_protected_nopar:Npn \fp_gcos:Nn {
+ \fp_cos_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_cos:Nn { c }
+\cs_generate_variant:Nn \fp_gcos:Nn { c }
+\cs_new_protected_nopar:Npn \fp_cos_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_trig_arg_tl
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \etex_ifcsname:D c_fp_cos ( \l_fp_trig_arg_tl ) _tl \tex_endcsname:D
+ \tex_else:D
+ \exp_after:wN \fp_cos_aux_i:
+ \tex_fi:D
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_cos ( \l_fp_trig_arg_tl ) _tl } }
+ }
+ \fp_tmp:w
+}
+\cs_new_protected_nopar:Npn \fp_cos_aux_i: {
+ \fp_trig_normalise:
+ \fp_cos_aux_ii:
+ \tex_ifnum:D \l_fp_output_integer_int = \c_one
+ \l_fp_output_exponent_int \c_zero
+ \tex_else:D
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_decimal_int \l_fp_output_extended_int
+ \l_fp_output_exponent_int -\c_nine
+ \tex_fi:D
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_cos ( \l_fp_trig_arg_tl ) _tl }
+ \tl_set:cx { c_fp_cos ( \l_fp_trig_arg_tl ) _tl }
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int > \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+}
+\cs_new_protected_nopar:Npn \fp_cos_aux_ii: {
+ \tex_ifcase:D \l_fp_trig_octant_int
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_cos:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_sin:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_sin:
+ \tex_or:D
+ \exp_after:wN \fp_trig_calc_cos:
+ \tex_fi:D
+ \tex_ifnum:D \l_fp_input_a_sign_int > \c_zero
+ \tex_ifnum:D \l_fp_trig_octant_int > \c_two
+ \l_fp_input_a_sign_int \c_minus_one
+ \tex_fi:D
+ \tex_else:D
+ \tex_ifnum:D \l_fp_trig_octant_int > \c_two
+ \tex_else:D
+ \l_fp_input_a_sign_int \c_one
+ \tex_fi:D
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_calc_cos: {
+ \tex_ifnum:D \l_fp_input_a_decimal_int = \c_zero
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \tex_else:D
+ \l_fp_trig_sign_int \c_minus_one
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \c_two
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int \c_three
+ \tex_ifnum:D \l_fp_trig_extended_int = \c_zero
+ \tex_ifnum:D \l_fp_trig_decimal_int = \c_zero
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \tex_else:D
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_one_thousand_million
+ \l_fp_output_extended_int \c_zero
+ \tex_fi:D
+ \tex_else:D
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int 999999999 \scan_stop:
+ \l_fp_output_extended_int \c_one_thousand_million
+ \tex_fi:D
+ \tex_advance:D \l_fp_output_extended_int -\l_fp_trig_extended_int
+ \tex_advance:D \l_fp_output_decimal_int -\l_fp_trig_decimal_int
+ \exp_after:wN \fp_trig_calc_aux:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_calc_sin: {
+ \l_fp_output_integer_int \c_zero
+ \tex_ifnum:D \l_fp_input_a_decimal_int = \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \tex_else:D
+ \l_fp_output_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_output_extended_int \l_fp_input_a_extended_int
+ \l_fp_trig_sign_int \c_one
+ \l_fp_trig_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_trig_extended_int \l_fp_input_a_extended_int
+ \l_fp_count_int \c_two
+ \exp_after:wN \fp_trig_calc_aux:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_trig_calc_aux: {
+ \l_fp_trig_sign_int -\l_fp_trig_sign_int
+ \fp_mul:NNNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_mul:NNNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \tex_advance:D \l_fp_count_int \c_one
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \tex_advance:D \l_fp_count_int \c_one
+ \tex_ifnum:D \l_fp_trig_decimal_int > \c_zero
+ \tex_ifnum:D \l_fp_trig_sign_int > \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \l_fp_trig_decimal_int
+ \tex_advance:D \l_fp_output_extended_int
+ \l_fp_trig_extended_int
+ \tex_ifnum:D \l_fp_output_extended_int < \c_one_thousand_million
+ \tex_else:D
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \tex_advance:D \l_fp_output_extended_int
+ -\c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D \l_fp_output_decimal_int < \c_one_thousand_million
+ \tex_else:D
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int
+ -\c_one_thousand_million
+ \tex_fi:D
+ \tex_else:D
+ \tex_advance:D \l_fp_output_decimal_int -\l_fp_trig_decimal_int
+ \tex_advance:D \l_fp_output_extended_int
+ -\l_fp_input_a_extended_int
+ \tex_ifnum:D \l_fp_output_extended_int < \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \c_minus_one
+ \tex_advance:D \l_fp_output_extended_int \c_one_thousand_million
+ \tex_fi:D
+ \tex_ifnum:D \l_fp_output_decimal_int < \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_minus_one
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \tex_fi:D
+ \tex_fi:D
+ \exp_after:wN \fp_trig_calc_aux:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_tan:Nn {
+ \fp_tan_aux:NNn \tl_set:Nn
+}
+\cs_new_protected_nopar:Npn \fp_gtan:Nn {
+ \fp_tan_aux:NNn \tl_gset:Nn
+}
+\cs_generate_variant:Nn \fp_tan:Nn { c }
+\cs_generate_variant:Nn \fp_gtan:Nn { c }
+\cs_new_protected_nopar:Npn \fp_tan_aux:NNn #1#2#3 {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_trig_arg_tl
+ {
+ \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
+ -
+ \tex_else:D
+ +
+ \tex_fi:D
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \tex_ifnum:D \l_fp_input_a_exponent_int < -\c_five
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \l_fp_trig_arg_tl }
+ }
+ \tex_else:D
+ \etex_ifcsname:D
+ c_fp_tan ( \l_fp_trig_arg_tl ) _tl
+ \tex_endcsname:D
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_i:
+ \tex_fi:D
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_tan ( \l_fp_trig_arg_tl ) _tl } }
+ }
+ \tex_fi:D
+ \fp_tmp:w
+}
+\cs_new_protected_nopar:Npn \fp_tan_aux_i: {
+ \tex_ifnum:D \l_fp_input_a_exponent_int < \c_ten
+ \exp_after:wN \fp_tan_aux_ii:
+ \tex_else:D
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ \c_zero_fp
+ \exp_after:wN \fp_trig_overflow_msg:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_tan_aux_ii: {
+ \fp_trig_normalise:
+ \fp_cos_aux_ii:
+ \tex_ifnum:D \l_fp_input_a_decimal_int = \c_zero
+ \tex_ifnum:D \l_fp_input_a_integer_int = \c_zero
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ \c_undefined_fp
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_iii:
+ \tex_fi:D
+ \tex_else:D
+ \exp_after:wN \fp_tan_aux_iii:
+ \tex_fi:D
+}
+\cs_new_protected_nopar:Npn \fp_tan_aux_iii: {
+ \l_fp_input_b_integer_int \l_fp_output_decimal_int
+ \l_fp_input_b_decimal_int \l_fp_output_extended_int
+ \l_fp_input_b_exponent_int -\c_nine
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_sin_aux_ii:
+ \l_fp_input_a_integer_int \l_fp_output_decimal_int
+ \l_fp_input_a_decimal_int \l_fp_output_extended_int
+ \l_fp_input_a_exponent_int -\c_nine
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tex_ifnum:D \l_fp_input_a_decimal_int = \c_zero
+ \tex_ifnum:D \l_fp_input_a_integer_int = \c_zero
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ \c_zero_fp
+ \tex_else:D
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_iv:
+ \tex_fi:D
+ \tex_else:D
+ \exp_after:wN \fp_tan_aux_iv:
+ \tex_fi:D
+}
+ \cs_new_protected_nopar:Npn \fp_tan_aux_iv: {
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
+ \l_fp_div_offset_int \c_one_hundred_million
+ \fp_div_loop:
+ \l_fp_output_exponent_int
+ \etex_numexpr:D
+ \l_fp_input_a_exponent_int - \l_fp_input_b_exponent_int
+ \scan_stop:
+ \tex_ifnum:D \l_fp_trig_octant_int < \c_three
+ \l_fp_output_sign_int \c_one
+ \tex_else:D
+ \l_fp_output_sign_int \c_minus_one
+ \tex_fi:D
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ \tl_set:cx { c_fp_tan ( \l_fp_trig_arg_tl ) _tl }
+ {
+ \tex_ifnum:D \l_fp_output_sign_int > \c_zero
+ +
+ \tex_else:D
+ -
+ \tex_fi:D
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \tex_number:D \etex_numexpr:D
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+}
+\prg_new_conditional:Npnn \fp_if_infinity:N #1 { p , T , F , TF } {
+ \tex_ifx:D #1 \c_infinity_fp
+ \prg_return_true:
+ \tex_else:D
+ \prg_return_false:
+ \tex_fi:D
+}
+\prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF } {
+ \tex_ifx:D #1 \c_undefined_fp
+ \prg_return_true:
+ \tex_else:D
+ \prg_return_false:
+ \tex_fi:D
+}
+\prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF } {
+ \tex_ifx:D #1 \c_zero_fp
+ \prg_return_true:
+ \tex_else:D
+ \prg_return_false:
+ \tex_fi:D
+}
+\prg_new_protected_conditional:Npnn \fp_compare:nNn #1#2#3 { T , F , TF }
+ {
\group_begin:
\fp_split:Nn a {#1}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
\fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
\fp_compare_aux:N #2
}
-\prg_new_protected_conditional:Npnn \fp_compare:NNN #1#2#3
- { T , F , TF } {
+\prg_new_protected_conditional:Npnn \fp_compare:NNN #1#2#3 { T , F , TF }
+ {
\group_begin:
\fp_read:N #3
- \l_fp_input_b_sign_int \l_fp_input_a_sign_int
- \l_fp_input_b_integer_int \l_fp_input_a_integer_int
- \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \l_fp_input_b_integer_int \l_fp_input_a_integer_int
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_exponent_int \l_fp_input_a_exponent_int
\fp_read:N #1
\fp_compare_aux:N #2
}
@@ -773,8 +2102,14 @@
\tex_ifnum:D \l_fp_input_a_sign_int = \l_fp_input_b_sign_int
\tex_ifnum:D \l_fp_input_a_integer_int = \l_fp_input_b_integer_int
\tex_ifnum:D \l_fp_input_a_decimal_int = \l_fp_input_b_decimal_int
- \group_end:
- \prg_return_true:
+ \tex_ifnum:D
+ \l_fp_input_a_exponent_int = \l_fp_input_b_exponent_int
+ \group_end:
+ \prg_return_true:
+ \tex_else:D
+ \group_end:
+ \prg_return_false:
+ \tex_fi:D
\tex_else:D
\group_end:
\prg_return_false:
@@ -823,270 +2158,102 @@
\tex_fi:D
}
\cs_new_protected_nopar:cpn { fp_compare_absolute_a > b: } {
- \tex_ifnum:D \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
+ \tex_ifnum:D \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
\group_end:
\prg_return_true:
\tex_else:D
- \tex_ifnum:D \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
- \group_end:
- \prg_return_false:
- \tex_else:D
- \tex_ifnum:D \l_fp_input_a_decimal_int > \l_fp_input_b_decimal_int
+ \tex_ifnum:D \l_fp_input_a_exponent_int < \l_fp_input_b_exponent_int
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
\group_end:
\prg_return_true:
\tex_else:D
\group_end:
\prg_return_false:
\tex_fi:D
- \tex_fi:D
- \tex_fi:D
-}
-\cs_new_protected_nopar:cpn { fp_compare_absolute_a < b: } {
- \tex_ifnum:D \l_fp_input_b_integer_int > \l_fp_input_a_integer_int
- \group_end:
- \prg_return_true:
- \tex_else:D
- \tex_ifnum:D \l_fp_input_b_integer_int < \l_fp_input_a_integer_int
- \group_end:
- \prg_return_false:
\tex_else:D
- \tex_ifnum:D \l_fp_input_b_decimal_int > \l_fp_input_a_decimal_int
+ \tex_ifnum:D \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
\group_end:
\prg_return_true:
\tex_else:D
- \group_end:
- \prg_return_false:
- \tex_fi:D
- \tex_fi:D
- \tex_fi:D
-}
-\keys_define:nn { fp } {
- precision .int_set:N = \l_fp_round_precision_int ,
- remove-trailing-zeros .bool_set:N = \l_fp_remove_zeros_bool ,
- round-mode .choice: ,
- round-mode
- / half-even .tl_set:N = \l_fp_round_mode_tl ,
- round-mode
- / half-from-zero .tl_set:N = \l_fp_round_mode_tl ,
- round-mode
- / none .tl_set:N = \l_fp_round_mode_tl ,
- round-mode
- / truncate .tl_set:N = \l_fp_round_mode_tl ,
-}
-\keys_set:nn { fp } {
- precision = 9 ,
- remove-trailing-zeros = true ,
- round-mode = none ,
-}
-\cs_new_protected_nopar:Npn \fp_to_tl:NN {
- \fp_to_tl_aux:NNN \tl_set:Nn
-}
-\cs_new_protected_nopar:Npn \fp_gto_tl:NN {
- \fp_to_tl_aux:NNN \tl_gset:Nn
-}
-\cs_generate_variant:Nn \fp_to_tl:NN { Nc }
-\cs_generate_variant:Nn \fp_to_tl:NN { c }
-\cs_generate_variant:Nn \fp_to_tl:NN { cc }
-\cs_generate_variant:Nn \fp_gto_tl:NN { Nc }
-\cs_generate_variant:Nn \fp_gto_tl:NN { c }
-\cs_generate_variant:Nn \fp_gto_tl:NN { cc }
-\cs_new_protected_nopar:Npn \fp_to_tl_aux:NNN #1#2#3 {
- \group_begin:
- \fp_read:N #2
- \use:c { fp_round_ \l_fp_round_mode_tl :}
- \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \tl_set:Nx \l_fp_tmp_tl
- {
- \tex_ifnum:D \l_fp_input_a_sign_int < \c_zero
- -
+ \tex_ifnum:D
+ \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
+ \group_end:
+ \prg_return_false:
+ \tex_else:D
+ \tex_ifnum:D
+ \l_fp_input_a_decimal_int > \l_fp_input_b_decimal_int
+ \group_end:
+ \prg_return_true:
+ \tex_else:D
+ \group_end:
+ \prg_return_false:
+ \tex_fi:D
\tex_fi:D
- \int_use:N \l_fp_input_a_integer_int
- \intexpr_compare:nNnT { \l_fp_round_precision_int } > { \c_zero }
- {
- .
- \bool_if:NTF \l_fp_remove_zeros_bool
- {
- \exp_after:wN \use_i:nn
- \exp_after:wN \fp_remove_zeros:NNNNNNNNN
- }
- { \exp_after:wN \use_none:n }
- \int_use:N \l_fp_input_a_decimal_int
- }
- }
- \exp_after:wN \group_end: \exp_after:wN
- #1 \exp_after:wN #3 \exp_after:wN { \l_fp_tmp_tl }
-}
-\cs_new_nopar:Npn \fp_remove_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {
- \fp_remove_zeros_aux:w #1#2#3#4#5#6#7#8#9 \q_stop 1
-}
-\cs_new_nopar:Npn \fp_remove_zeros_aux:w #1#2 \q_stop #3 {
- #1
- \intexpr_compare:nNnTF { 0 #2 } = { \c_zero }
- {
- \intexpr_compare:nNnF { \l_fp_round_precision_int } < { #3 + 1 }
- {
- \intexpr_compare:nNnT {#3} < { 9 }
- { \fp_remove_zeros_aux:w #2 \q_stop { #3 + 1 } }
- }
- }
- {
- \intexpr_compare:nNnT {#3} < { 9 }
- { \fp_remove_zeros_aux:w #2 \q_stop { #3 + 1 } }
- }
-}
-\cs_new_protected_nopar:cpn { fp_round_half-from-zero: } {
- \tex_ifnum:D \l_fp_round_precision_int < \c_nine
- \exp_after:wN \fp_round_from_zero:
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_round_from_zero: {
- \bool_set_false:N \l_fp_round_carry_bool
- \l_fp_round_position_int \c_eight
- \tl_clear:N \l_fp_round_decimal_tl
- \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \exp_after:wN \use_i:nn \exp_after:wN
- \fp_round_from_zero_aux:NNNNNNNNN
- \int_use:N \l_fp_input_a_decimal_int
-}
-\cs_new_protected_nopar:Npn \fp_round_from_zero_aux:NNNNNNNNN
- #1#2#3#4#5#6#7#8#9 {
- \fp_round_from_zero_decimal:N #9#8#7#6#5#4#3#2#1
- \fp_round_from_zero_integer:
-}
-\cs_new_protected_nopar:Npn \fp_round_from_zero_decimal:N #1 {
- \tex_ifnum:D \l_fp_round_position_int < \l_fp_round_precision_int
- \bool_if:NTF \l_fp_round_carry_bool
- { \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop: }
- { \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop: }
- \tex_ifnum:D \l_fp_tmp_int = \c_ten
- \l_fp_tmp_int \c_zero
- \tex_else:D
- \bool_set_false:N \l_fp_round_carry_bool
- \tex_fi:D
- \tl_set:Nx \l_fp_round_decimal_tl
- { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
- \tex_else:D
- \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
- \tex_ifnum:D \l_fp_round_position_int = \l_fp_round_precision_int
- \tex_ifnum:D #1 > \c_four
- \bool_set_true:N \l_fp_round_carry_bool
\tex_fi:D
\tex_fi:D
\tex_fi:D
- \tex_advance:D \l_fp_round_position_int \c_minus_one
- \tex_ifnum:D \l_fp_round_position_int > \c_minus_one
- \exp_after:wN \fp_round_from_zero_decimal:N
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_round_from_zero_integer: {
- \bool_if:NT \l_fp_round_carry_bool
- { \tex_advance:D \l_fp_input_a_integer_int \c_one }
- \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
-}
-\cs_new_protected_nopar:cpn { fp_round_half-even: } {
- \tex_ifnum:D \l_fp_round_precision_int < \c_nine
- \exp_after:wN \fp_round_even:
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_round_even: {
- \bool_set_false:N \l_fp_round_carry_bool
- \l_fp_round_position_int \c_eight
- \tl_clear:N \l_fp_round_decimal_tl
- \int_zero:N \l_fp_round_discard_int
- \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
- \exp_after:wN \use_i:nn \exp_after:wN
- \fp_round_even_aux:NNNNNNNNN
- \int_use:N \l_fp_input_a_decimal_int
-}
-\cs_new_protected_nopar:Npn \fp_round_even_aux:NNNNNNNNN
- #1#2#3#4#5#6#7#8#9 {
- \fp_round_even_decimal:N #9#8#7#6#5#4#3#2#1
- \fp_round_even_integer:
}
-\cs_new_protected_nopar:Npn \fp_round_even_decimal:N #1 {
- \tex_ifnum:D \l_fp_round_position_int < \l_fp_round_precision_int
- \bool_if:NTF \l_fp_round_carry_bool
- {
- \tex_ifnum:D \l_fp_round_discard_int = \c_zero
- \l_fp_round_discard_int \c_one
- \tex_ifodd:D #1 \scan_stop:
- \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop:
- \tex_else:D
- \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop:
- \tex_fi:D
- \tex_else:D
- \l_fp_tmp_int \etex_numexpr:D #1 + \c_one \scan_stop:
- \tex_fi:D
- }
- { \l_fp_tmp_int \etex_numexpr:D #1 \scan_stop: }
- \tex_ifnum:D \l_fp_tmp_int = \c_ten
- \l_fp_tmp_int \c_zero
+\cs_new_protected_nopar:cpn { fp_compare_absolute_a < b: } {
+ \tex_ifnum:D \l_fp_input_b_exponent_int > \l_fp_input_a_exponent_int
+ \tex_ifnum:D
+ \etex_numexpr:D
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \group_end:
+ \prg_return_false:
\tex_else:D
- \bool_set_false:N \l_fp_round_carry_bool
+ \group_end:
+ \prg_return_true:
\tex_fi:D
- \tl_set:Nx \l_fp_round_decimal_tl
- { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
\tex_else:D
- \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
- \tex_ifnum:D \l_fp_round_position_int = \l_fp_round_precision_int
- \tex_ifnum:D #1 > \c_four
- \bool_set_true:N \l_fp_round_carry_bool
- \tex_ifnum:D #1 = \c_five
+ \tex_ifnum:D \l_fp_input_b_exponent_int < \l_fp_input_a_exponent_int
+ \group_end:
+ \prg_return_false:
+ \tex_else:D
+ \tex_ifnum:D \l_fp_input_b_integer_int > \l_fp_input_a_integer_int
+ \group_end:
+ \prg_return_true:
+ \tex_else:D
+ \tex_ifnum:D
+ \l_fp_input_b_integer_int < \l_fp_input_a_integer_int
+ \group_end:
+ \prg_return_false:
\tex_else:D
- \l_fp_round_discard_int \c_one
+ \tex_ifnum:D
+ \l_fp_input_b_decimal_int > \l_fp_input_a_decimal_int
+ \group_end:
+ \prg_return_true:
+ \tex_else:D
+ \group_end:
+ \prg_return_false:
+ \tex_fi:D
\tex_fi:D
\tex_fi:D
- \tex_else:D
- \tex_advance:D \l_fp_round_discard_int #1 \scan_stop:
\tex_fi:D
\tex_fi:D
- \tex_advance:D \l_fp_round_position_int \c_minus_one
- \tex_ifnum:D \l_fp_round_position_int > \c_minus_one
- \exp_after:wN \fp_round_even_decimal:N
- \tex_fi:D
-}
-\cs_new_protected_nopar:Npn \fp_round_even_integer: {
- \bool_if:NT \l_fp_round_carry_bool
- {
- \tex_ifnum:D \l_fp_round_discard_int = \c_zero
- \tex_ifodd:D \l_fp_input_a_integer_int
- \tex_advance:D \l_fp_input_a_integer_int \c_one
- \tex_fi:D
- \tex_else:D
- \tex_advance:D \l_fp_input_a_integer_int \c_one
- \tex_fi:D
- }
- \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
-}
-\cs_new_protected_nopar:Npn \fp_round_none: {
- \l_fp_round_precision_int \c_one
-}
-\cs_new_protected_nopar:Npn \fp_round_truncate: {
- \intexpr_compare:nNnF { \l_fp_round_precision_int } > { 8 }
- {
- \intexpr_compare:nNnTF { \l_fp_round_precision_int } < { 1 }
- { \l_fp_input_a_decimal_int \c_zero \scan_stop: }
- {
- \int_set:Nn \l_fp_tmp_int
- {
- \prg_replicate:nn { 9 - \l_fp_round_precision_int }
- { 10 * }
- 1
- }
- \tex_divide:D \l_fp_input_a_decimal_int \l_fp_tmp_int
- \tex_multiply:D \l_fp_input_a_decimal_int \l_fp_tmp_int
- }
- }
}
-\cs_new_protected_nopar:Npn \fp_msg_overflow: {
+
+\msg_kernel_new:nnnn { fpu } { overflow }
+ { Number~too~big. }
+ {
+ The~input~given~is~too~big~for~the~LaTeX~floating~point~unit. \\
+ Further~errors~may~well~occur!
+ }
+\cs_new_protected_nopar:Npn \fp_overflow_msg: {
\msg_kernel_error:nn { fpu } { overflow }
}
-\msg_kernel_new:nnnn { fpu } { overflow }
- { Arithmetic~overflow. }
+\msg_kernel_new:nnnn { fpu } { trigonometric-overflow }
+ { Number~too~big~for~trigonometry~unit. }
{
- The~calculation~requested~exceeds~the~capacity \\
- of~the~fixed-point~unit.
+ The~trigonometry~code~can~only~work~with~numbers~smaller~
+ than~1000000000.
}
+\cs_new_protected_nopar:Npn \fp_trig_overflow_msg: {
+ \msg_kernel_error:nn { fpu } { trigonometric-overflow }
+}
%%
%%
%% End of file `l3fp.sty'.
diff --git a/Master/texmf-dist/tex/latex/expl3/l3prg.sty b/Master/texmf-dist/tex/latex/expl3/l3prg.sty
index 5476a648597..38112ebffa8 100644
--- a/Master/texmf-dist/tex/latex/expl3/l3prg.sty
+++ b/Master/texmf-dist/tex/latex/expl3/l3prg.sty
@@ -48,7 +48,7 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
-\GetIdInfo$Id: l3prg.dtx 1853 2010-03-21 09:11:08Z joseph $
+\GetIdInfo$Id: l3prg.dtx 1992 2010-08-04 20:41:40Z joseph $
{L3 Experimental control structures}
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
@@ -478,6 +478,90 @@
}
}
}
+\cs_new_protected:Npn \prg_new_map_functions:Nn #1#2 {
+ \cs_if_free:cTF { #2 _map_function:NN }
+ { \prg_set_map_functions:Nn #1 {#2} }
+ {
+ \msg_kernel_error:nnx { code } { csname-already-defined }
+ { \token_to_str:c { #2 _map_function:NN } }
+ }
+}
+\cs_new_protected:Npn \prg_set_map_functions:Nn #1#2 {
+ \cs_gset_nopar:cpx { #2 _map_function:NN } ##1##2
+ {
+ \exp_not:N \tl_if_empty:NF ##1
+ {
+ \exp_not:N \exp_after:wN
+ \exp_not:c { #2 _map_function_aux:Nw }
+ \exp_not:N \exp_after:wN ##2 ##1
+ \exp_not:n { #1 \q_recursion_tail #1 \q_recursion_stop }
+ }
+ }
+ \cs_gset:cpx { #2 _map_function:nN } ##1##2
+ {
+ \exp_not:N \tl_if_blank:nF {##1}
+ {
+ \exp_not:c { #2 _map_function_aux:Nw } ##2 ##1
+ \exp_not:n { #1 \q_recursion_tail #1 \q_recursion_stop }
+ }
+ }
+ \cs_gset:cpx { #2 _map_function_aux:Nw } ##1##2 #1
+ {
+ \exp_not:N \quark_if_recursion_tail_stop:n {##2}
+ ##1 {##2}
+ \exp_not:c { #2 _map_function_aux:Nw } ##1
+ }
+ \cs_if_free:cT { g_ #2 _map_inline_int }
+ { \int_new:c { g_ #2 _map_inline_int } }
+ \cs_gset_protected_nopar:cpx { #2 _map_inline:Nn } ##1##2
+ {
+ \exp_not:N \tl_if_empty:NF ##1
+ {
+ \exp_not:N \int_gincr:N \exp_not:c { g_ #2 _map_inline_int }
+ \cs_gset:cpn
+ {
+ #2 _map_inline_
+ \exp_not:N \int_use:N \exp_not:c { g_ #2 _map_inline_int }
+ :n
+ }
+ ####1 {##2}
+ \exp_not:N \exp_last_unbraced:NcV
+ \exp_not:c { #2 _map_function_aux:Nw }
+ {
+ #2 _map_inline_
+ \exp_not:N \int_use:N \exp_not:c { g_ #2 _map_inline_int }
+ :n
+ }
+ ##1 \exp_not:n { #1 \q_recursion_tail #1 \q_recursion_stop }
+ \exp_not:N \int_gdecr:N \exp_not:c { g_ #2 _map_inline_int }
+ }
+ }
+ \cs_gset_protected:cpx { #2 _map_inline:nn } ##1##2
+ {
+ \exp_not:N \tl_if_empty:nF {##1}
+ {
+ \exp_not:N \int_gincr:N \exp_not:c { g_ #2 _map_inline_int }
+ \cs_gset:cpn
+ {
+ #2 _map_inline_
+ \exp_not:N \int_use:N \exp_not:c { g_ #2 _map_inline_int }
+ :n
+ }
+ ####1 {##2}
+ \exp_not:N \exp_args:Nc
+ \exp_not:c { #2 _map_function_aux:Nw }
+ {
+ #2 _map_inline_
+ \exp_not:N \int_use:N \exp_not:c { g_ #2 _map_inline_int }
+ :n
+ }
+ ##1 \exp_not:n { #1 \q_recursion_tail #1 \q_recursion_stop }
+ \exp_not:N \int_gdecr:N \exp_not:c { g_ #2 _map_inline_int }
+ }
+ }
+ \cs_gset_eq:cN { #2 _map_break: }
+ \use_none_delimit_by_q_recursion_stop:w
+}
%%
%%
%% End of file `l3prg.sty'.