% \iffalse meta-comment
%%
%% File: l3fp-assign.dtx Copyright (C) 2011-2014 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 LaTeX Project Team.
%%
%% -----------------------------------------------------------------------
%%
%
%<*driver>
\documentclass[full]{l3doc}
\GetIdInfo$Id: l3fp-assign.dtx 4712 2014-04-30 08:17:49Z joseph $
  {L3 Floating-point assignments}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{The \textsf{l3fp-assign} package\thanks{This file
%         has version number \ExplFileVersion, last
%         revised \ExplFileDate.}\\
% Floating point expressions}
% \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-assign} implementation}
%
%    \begin{macrocode}
%<*initex|package>
%    \end{macrocode}
%
%    \begin{macrocode}
%<@@=fp>
%    \end{macrocode}
%
% \subsection{Assigning values}
%
% \begin{macro}{\fp_new:N}
%   Floating point variables are initialized to be $+0$.
%    \begin{macrocode}
\cs_new_protected:Npn \fp_new:N #1
  { \cs_new_eq:NN #1 \c_zero_fp }
\cs_generate_variant:Nn \fp_new:N {c}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}
%   {
%     \fp_set:Nn, \fp_set:cn,
%     \fp_gset:Nn, \fp_gset:cn,
%     \fp_const:Nn, \fp_const:cn
%   }
%   Simply use \cs{@@_parse:n} within various \texttt{f}-expanding
%   assignments.
%    \begin{macrocode}
\cs_new_protected:Npn \fp_set:Nn   #1#2
  { \tl_set:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } }
\cs_new_protected:Npn \fp_gset:Nn  #1#2
  { \tl_gset:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } }
\cs_new_protected:Npn \fp_const:Nn #1#2
  { \tl_const:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } }
\cs_generate_variant:Nn \fp_set:Nn {c}
\cs_generate_variant:Nn \fp_gset:Nn {c}
\cs_generate_variant:Nn \fp_const:Nn {c}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}
%   {
%     \fp_set_eq:NN , \fp_set_eq:cN , \fp_set_eq:Nc , \fp_set_eq:cc,
%     \fp_gset_eq:NN, \fp_gset_eq:cN, \fp_gset_eq:Nc, \fp_gset_eq:cc
%   }
%   Copying a floating point is the same as copying the underlying token
%   list.
%    \begin{macrocode}
\cs_new_eq:NN \fp_set_eq:NN  \tl_set_eq:NN
\cs_new_eq:NN \fp_gset_eq:NN \tl_gset_eq:NN
\cs_generate_variant:Nn \fp_set_eq:NN  { c , Nc , cc }
\cs_generate_variant:Nn \fp_gset_eq:NN { c , Nc , cc }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fp_zero:N, \fp_zero:c, \fp_gzero:N, \fp_gzero:c}
%   Setting a floating point to zero: copy \cs{c_zero_fp}.
%    \begin{macrocode}
\cs_new_protected:Npn \fp_zero:N #1 { \fp_set_eq:NN #1 \c_zero_fp }
\cs_new_protected:Npn \fp_gzero:N #1 { \fp_gset_eq:NN #1 \c_zero_fp }
\cs_generate_variant:Nn \fp_zero:N  { c }
\cs_generate_variant:Nn \fp_gzero:N { c }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}
%   {\fp_zero_new:N, \fp_zero_new:c, \fp_gzero_new:N, \fp_gzero_new:c}
%   Set the floating point to zero, or define it if needed.
%    \begin{macrocode}
\cs_new_protected:Npn \fp_zero_new:N #1
  { \fp_if_exist:NTF #1 { \fp_zero:N #1 } { \fp_new:N #1 } }
\cs_new_protected:Npn \fp_gzero_new:N #1
  { \fp_if_exist:NTF #1 { \fp_gzero:N #1 } { \fp_new:N #1 } }
\cs_generate_variant:Nn \fp_zero_new:N  { c }
\cs_generate_variant:Nn \fp_gzero_new:N { c }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Updating values}
%
% These match the equivalent functions in \pkg{l3int} and \pkg{l3skip}.
%
% \begin{macro}
%   {
%     \fp_add:Nn, \fp_add:cn, \fp_gadd:Nn, \fp_gadd:cn,
%     \fp_sub:Nn, \fp_sub:cn, \fp_gsub:Nn, \fp_gsub:cn,
%   }
% \begin{macro}[aux]{\@@_add:NNNn}
%   For the sake of error recovery we should not simply set |#1| to
%   $|#1| \pm (|#2|)$: for instance, if |#2| is % ^^A(
%   |0)+2|, the parsing error would be raised at the last closing
%   parenthesis rather than at the closing parenthesis in the user
%   argument.  Thus we evaluate |#2| instead of just putting
%   parentheses.  As an optimization we use \cs{@@_parse:n} rather than
%   \cs{fp_eval:n}, which would convert the result away from the
%   internal representation and back.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \fp_add:Nn  { \@@_add:NNNn \fp_set:Nn  + }
\cs_new_protected_nopar:Npn \fp_gadd:Nn { \@@_add:NNNn \fp_gset:Nn + }
\cs_new_protected_nopar:Npn \fp_sub:Nn  { \@@_add:NNNn \fp_set:Nn  - }
\cs_new_protected_nopar:Npn \fp_gsub:Nn { \@@_add:NNNn \fp_gset:Nn - }
\cs_new_protected:Npn \@@_add:NNNn #1#2#3#4
  { #1 #3 { #3 #2 \@@_parse:n {#4} } }
\cs_generate_variant:Nn \fp_add:Nn  { c }
\cs_generate_variant:Nn \fp_gadd:Nn { c }
\cs_generate_variant:Nn \fp_sub:Nn  { c }
\cs_generate_variant:Nn \fp_gsub:Nn { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Showing values}
%
% \begin{macro}{\fp_show:N, \fp_show:c, \fp_show:n}
%   This shows the result of computing its argument.  The
%   \cs{__msg_show_variable:n} auxiliary expects its input in a slightly
%   odd form, starting with |>~|, and displays the rest.
%    \begin{macrocode}
\cs_new_protected:Npn \fp_show:N #1
  {
    \fp_if_exist:NTF #1
      { \__msg_show_variable:n { > ~ \fp_to_tl:N #1 } }
      {
        \__msg_kernel_error:nnx { kernel } { variable-not-defined }
          { \token_to_str:N #1 }
      }
  }
\cs_new_protected:Npn \fp_show:n #1
  { \__msg_show_variable:n { > ~ \fp_to_tl:n {#1} } }
\cs_generate_variant:Nn \fp_show:N { c }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Some useful constants and scratch variables}
%
% \begin{variable}{\c_one_fp, \c_e_fp}
%   Some constants.
%    \begin{macrocode}
\fp_const:Nn \c_e_fp          { 2.718 2818 2845 9045 }
\fp_const:Nn \c_one_fp        { 1 }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\c_pi_fp, \c_one_degree_fp}
%   We simply round $\pi$ to the closest multiple of $10^{-15}$.
%    \begin{macrocode}
\fp_const:Nn \c_pi_fp         { 3.141 5926 5358 9793 }
\fp_const:Nn \c_one_degree_fp { 0.0 1745 3292 5199 4330 }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_tmpa_fp, \l_tmpb_fp, \g_tmpa_fp, \g_tmpb_fp}
%   Scratch variables are simply initialized there.
%    \begin{macrocode}
\fp_new:N \l_tmpa_fp
\fp_new:N \l_tmpb_fp
\fp_new:N \g_tmpa_fp
\fp_new:N \g_tmpb_fp
%    \end{macrocode}
% \end{variable}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintChanges
%
% \PrintIndex
