% \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} % % \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} % % \end{macrocode} % % \end{implementation} % % \PrintChanges % % \PrintIndex