% \iffalse meta-comment
%
%% File: l3fp-old.dtx Copyright (C) 2012 The LaTeX3 Project
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
%% license or (at your option) any later version.  The latest version
%% of this license is in the file
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% This file is part of the "l3kernel bundle" (The Work in LPPL)
%% and all files in that bundle must be distributed together.
%%
%% The released version of this bundle is available from CTAN.
%%
%% -----------------------------------------------------------------------
%%
%% The development version of the bundle can be found at
%%
%%    http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
%%%%%%%%%%%
%% NOTE: %%
%%%%%%%%%%%
%%
%%   Snapshots taken from the repository represent work in progress and may
%%   not work or may contain conflicting material!  We therefore ask
%%   people _not_ to put them into distributions, archives, etc. without
%%   prior consultation with the LaTeX3 Project Team.
%%
%% -----------------------------------------------------------------------
%%
%
%<*driver>
\RequirePackage{l3bootstrap}
\GetIdInfo$Id: l3fp-old.dtx 4163 2012-08-30 16:33:11Z bruno $
  {L3 Experimental floating-points (old)}
\documentclass[full]{l3doc}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \pkg{l3fp-old} package\\ Floating-points (old)^^A
%   \thanks{This file describes v\ExplFileVersion,
%      last revised \ExplFileDate.}^^A
% }
%
% \author{^^A
%  The \LaTeX3 Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released \ExplFileDate}
%
% \maketitle
%
% \begin{documentation}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3fp-old} implementation}
%
%    \begin{macrocode}
%<*initex|package>
%    \end{macrocode}
%
%    \begin{macrocode}
%<@@=fp>
%    \end{macrocode}
%
% \subsection{Compatibility}
%
% \begin{variable}{\c_undefined_fp}
%   The old floating point number \cs{c_undefined_fp} is now implemented
%   as a \texttt{nan}.
%    \begin{macrocode}
\fp_const:Nn \c_undefined_fp { nan }
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}[pTF]{\fp_if_undefined:N}
%   An old floating point is undefined if it is \texttt{inf} or
%   \texttt{nan}, \emph{i.e.}, if its type is $2$ or $3$.
%    \begin{macrocode}
\prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF }
  { \exp_after:wN \@@_if_undefined:w #1 }
\cs_new:Npn \@@_if_undefined:w \s_@@ \@@_chk:w #1#2;
  {
    \if_int_compare:w #1 > \c_one
      \prg_return_true: \else: \prg_return_false: \fi:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF]{\fp_if_zero:N}
%   An old floating point is zero if it is $\pm 0$, \emph{i.e.}, its
%   type is $0$.
%    \begin{macrocode}
\prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF }
  { \exp_after:wN \@@_if_zero:w #1 }
\cs_new:Npn \@@_if_zero:w \s_@@ \@@_chk:w #1#2;
  { \if_meaning:w #1 0 \prg_return_true: \else: \prg_return_false: \fi: }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}
%   {
%     \fp_abs:N , \fp_abs:c , \fp_gabs:N , \fp_gabs:c ,
%     \fp_neg:N , \fp_neg:c , \fp_gneg:N , \fp_gneg:c ,
%   }
% \begin{macro}[aux]{\@@_abs:NNN}
%   Simply expand the floating point variable to feed it to
%   \cs{@@_abs_o:w} or \cs{@@_-_o:w}, expanded within an expanding
%   token list assignment.  The \cs{prg_do_nothing:} is not necessary,
%   but it reminds us more clearly that \cs{@@_abs_o:w} and
%   \cs{@@_-_o:w} expand after their result.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_abs:N  { \@@_abs:NNN \tl_set:Nx  \@@_abs_o:w }
\cs_new_protected_nopar:Npn \fp_gabs:N { \@@_abs:NNN \tl_gset:Nx \@@_abs_o:w }
\cs_new_protected_nopar:Npx \fp_neg:N
  {
    \exp_not:N \@@_abs:NNN
    \exp_not:N \tl_set:Nx
    \exp_not:c { @@_-_o:w }
  }
\cs_new_protected_nopar:Npx \fp_gneg:N
  {
    \exp_not:N \@@_abs:NNN
    \exp_not:N \tl_gset:Nx
    \exp_not:c { @@_-_o:w }
  }
\cs_new_protected:Npn \@@_abs:NNN #1#2#3
  { #1 #3 { \exp_after:wN #2 #3 \prg_do_nothing: } }
\cs_generate_variant:Nn \fp_abs:N  { c }
\cs_generate_variant:Nn \fp_gabs:N { c }
\cs_generate_variant:Nn \fp_neg:N  { c }
\cs_generate_variant:Nn \fp_gneg:N { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}
%   {
%     \fp_mul:Nn, \fp_mul:cn, \fp_gmul:Nn, \fp_gmul:cn,
%     \fp_div:Nn, \fp_div:cn, \fp_gdiv:Nn, \fp_gdiv:cn,
%     \fp_pow:Nn, \fp_pow:cn, \fp_gpow:Nn, \fp_gpow:cn,
%   }
% \begin{macro}[aux]{\@@_mul:NNNn}
%   See \cs{fp_add:Nn} for details.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_mul:Nn  { \@@_mul:NNNn \fp_set:Nn  * }
\cs_new_protected_nopar:Npn \fp_gmul:Nn { \@@_mul:NNNn \fp_gset:Nn * }
\cs_new_protected_nopar:Npn \fp_div:Nn  { \@@_mul:NNNn \fp_set:Nn  / }
\cs_new_protected_nopar:Npn \fp_gdiv:Nn { \@@_mul:NNNn \fp_gset:Nn / }
\cs_new_protected_nopar:Npn \fp_pow:Nn  { \@@_mul:NNNn \fp_set:Nn  ^ }
\cs_new_protected_nopar:Npn \fp_gpow:Nn { \@@_mul:NNNn \fp_gset:Nn ^ }
\cs_new_protected:Npn \@@_mul:NNNn #1#2#3#4
  { #1 #3 { #3 #2 \@@_parse:n {#4} } }
\cs_generate_variant:Nn \fp_mul:Nn  { c }
\cs_generate_variant:Nn \fp_gmul:Nn { c }
\cs_generate_variant:Nn \fp_div:Nn  { c }
\cs_generate_variant:Nn \fp_gdiv:Nn { c }
\cs_generate_variant:Nn \fp_pow:Nn  { c }
\cs_generate_variant:Nn \fp_gpow:Nn { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}
%   {
%     \fp_exp:Nn, \fp_exp:cn, \fp_gexp:Nn, \fp_gexp:cn,
%     \fp_ln:Nn , \fp_ln:cn , \fp_gln:Nn , \fp_gln:cn ,
%     \fp_sin:Nn, \fp_sin:cn, \fp_gsin:Nn, \fp_gsin:cn,
%     \fp_cos:Nn, \fp_cos:cn, \fp_gcos:Nn, \fp_gcos:cn,
%     \fp_tan:Nn, \fp_tan:cn, \fp_gtan:Nn, \fp_gtan:cn,
%   }
% \begin{macro}[aux]
%   {\@@_assign_to:nNNNn, \@@_assign_to_i:wNNNn, \@@_assign_to_ii:NnNNN}
%   Here, an added twist is that each value computed by these expensive
%   unary operations is stored as a constant floating point number.
%    \begin{macrocode}
\cs_set_protected:Npn \@@_tmp:w #1#2#3#4#5
  {
    \cs_new_protected_nopar:Npn #1 { #5 {#4} \tl_set_eq:NN  #3 }
    \cs_new_protected_nopar:Npn #2 { #5 {#4} \tl_gset_eq:NN #3 }
    \cs_generate_variant:Nn #1 { c }
    \cs_generate_variant:Nn #2 { c }
  }
\@@_tmp:w \fp_exp:Nn \fp_gexp:Nn \@@_exp_o:w {exp} \@@_assign_to:nNNNn
\@@_tmp:w \fp_ln:Nn  \fp_gln:Nn  \@@_ln_o:w  {ln } \@@_assign_to:nNNNn
\@@_tmp:w \fp_sin:Nn \fp_gsin:Nn \@@_sin_o:w {sin} \@@_assign_to:nNNNn
\@@_tmp:w \fp_cos:Nn \fp_gcos:Nn \@@_cos_o:w {cos} \@@_assign_to:nNNNn
\@@_tmp:w \fp_tan:Nn \fp_gtan:Nn \@@_tan_o:w {tan} \@@_assign_to:nNNNn
\cs_new_protected:Npn \@@_assign_to:nNNNn #1#2#3#4#5
  {
    \exp_after:wN \@@_assign_to_i:wNNNn
    \tex_romannumeral:D -`0 \@@_parse:n {#5} {#1} #2#3#4
  }
\cs_new_protected:Npn \@@_assign_to_i:wNNNn \s_@@ \@@_chk:w #1#2#3; #4
  {
    \exp_args:Nc \@@_assign_to_ii:NnNNN
      { c_@@_ #4 [ #1 # 2 \if_meaning:w 1 #1 #3 \fi: ] _fp }
      { #1#2#3 }
  }
\cs_new_protected:Npn \@@_assign_to_ii:NnNNN #1#2#3#4#5
  {
    \cs_if_exist:NF #1
      { \tl_const:Nx #1 { #4 \s_@@ \@@_chk:w #2; } }
    #3 #5 #1
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}[TF]{\fp_compare:NNN}
%   Comparisons used to be easier between floating points stored in
%   variables. No more.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_compare:NNNTF { \fp_compare:nNnTF }
\cs_new_protected_nopar:Npn \fp_compare:NNNT  { \fp_compare:nNnT  }
\cs_new_protected_nopar:Npn \fp_compare:NNNF  { \fp_compare:nNnF  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp_round_places:Nn, \fp_ground_places:Nn}
% \begin{macro}[aux]{\@@_round_places:NNn}
%   Rounding to a given number of places is easy, since it is provided
%   by the \pkg{l3fp-round} module.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_round_places:Nn
  { \@@_round_places:NNn \tl_set:Nx }
\cs_new_protected_nopar:Npn \fp_ground_places:Nn
  { \@@_round_places:NNn \tl_gset:Nx }
\cs_new_protected:Npn \@@_round_places:NNn #1#2#3
  {
    #1 #2
      {
        \exp_after:wN \exp_after:wN
        \exp_after:wN \@@_round:Nwn
        \exp_after:wN \exp_after:wN
        \exp_after:wN \@@_round_to_nearest:NNN
        \exp_after:wN #2
        \exp_after:wN { \int_use:N \__int_eval:w #3 }
      }
  }
\cs_generate_variant:Nn \fp_round_places:Nn { c }
\cs_generate_variant:Nn \fp_ground_places:Nn { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\fp_round_figures:Nn, \fp_ground_figures:Nn}
%   Rounding to a given number of figures is the same as rounding to a
%   number of places, after shifting by the exponent of the argument.
%    \begin{macrocode}
\cs_new_protected:Npn \fp_round_figures:Nn #1#2
  {
    \@@_round_places:NNn \tl_set:Nx #1
      { #2 - \exp_after:wN \@@_exponent:w #1 }
  }
\cs_new_protected:Npn \fp_ground_figures:Nn #1#2
  {
    \@@_round_places:NNn \tl_gset:Nx #1
      { #2 - \exp_after:wN \@@_exponent:w #1 }
  }
\cs_generate_variant:Nn \fp_round_figures:Nn { c }
\cs_generate_variant:Nn \fp_ground_figures:Nn { c }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
