summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx226
1 files changed, 115 insertions, 111 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
index 057cef4b176..8f0c2848ea4 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
@@ -35,8 +35,8 @@
%%
%
%<*driver>
-\RequirePackage{l3names}
-\GetIdInfo$Id: l3fp-convert.dtx 3986 2012-07-15 19:23:51Z joseph $
+\RequirePackage{l3bootstrap}
+\GetIdInfo$Id: l3fp-convert.dtx 4090 2012-08-14 07:57:01Z joseph $
{L3 Floating-point conversion}
\documentclass[full]{l3doc}
\begin{document}
@@ -66,9 +66,6 @@
%
% \begin{documentation}
%
-% ^^A todo: tests
-% ^^A todo: doc functions
-%
% \end{documentation}
%
% \begin{implementation}
@@ -92,7 +89,7 @@
% as an end-delimiter for its first argument, and the second argument
% is the same \texttt{loop} auxiliary. Once the last trailing zero is
% reached, the second argument will be the \texttt{dot} auxiliary,
-% which removes a trailing dot if any. We then cleanup with the
+% which removes a trailing dot if any. We then clean-up with the
% \texttt{end} auxiliary, keeping only the number.
% \begin{macrocode}
\cs_new:Npn \@@_trim_zeros:w #1 ;
@@ -109,28 +106,17 @@
%
% \subsection{Scientific notation}
%
-% \begin{variable}{\c_@@_scientific_inf_tl}
-% Result of converting $\infty$ to a scientific representation: after
-% triggering an \enquote{invalid operation} exception,
-% \cs{fp_to_scientific:n} yields that result, larger than any finite
-% floating point number.
-% \begin{macrocode}
-\tl_const:Nx \c_@@_scientific_inf_tl
- { 1e \int_use:N \c_@@_max_exponent_int }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}
+% \begin{macro}[EXP]
% {\fp_to_scientific:N, \fp_to_scientific:c, \fp_to_scientific:n}
% The three public functions evaluate their argument, then pass it to
% \cs{@@_to_scientific:w}.
% \begin{macrocode}
\cs_new:Npn \fp_to_scientific:N #1 { \exp_after:wN \@@_to_scientific:w #1 }
\cs_generate_variant:Nn \fp_to_scientific:N { c }
-\cs_new:Npn \fp_to_scientific:n #1
+\cs_new_nopar:Npn \fp_to_scientific:n
{
\exp_after:wN \@@_to_scientific:w
- \tex_romannumeral:D -`0 \@@_parse:n {#1}
+ \tex_romannumeral:D -`0 \@@_parse:n
}
% \end{macrocode}
% \end{macro}
@@ -143,43 +129,63 @@
% }
% Expressing an internal floating point number in scientific notation
% is quite easy: no rounding, and the format is very well defined.
-% First cater for the sign: negative numbers (|#2=2|) start with |-|.
-% Then filter the special cases: we insert \cs{prg_do_nothing:}
-% because \cs{@@_invalid_operation:Nnw} expands after taking one
-% floating point argument. In the normal case, decrement the exponent
-% and unbrace the $4$ brace groups, then in a second step grab the
-% first digit (previously hidden in braces) to order the various parts
-% correctly. Finally trim zeros.
+% First cater for the sign: negative numbers ($|#2|=2$) start
+% with~|-|; we then only need to care about positive numbers and
+% \texttt{nan}. Then filter the special cases: $\pm0$~are represented
+% as~|0|; infinities are converted to a number slightly larger than
+% the largest after an \enquote{invalid_operation} exception;
+% \texttt{nan} is represented as~|0| after an
+% \enquote{invalid_operation} exception. In the normal case,
+% decrement the exponent and unbrace the $4$ brace groups, then in a
+% second step grab the first digit (previously hidden in braces) to
+% order the various parts correctly. Finally trim zeros. The whole
+% construction is within a call to \cs{tl_to_lowercase:n}, responsible
+% for creating |e| with category \enquote{other}.
% \begin{macrocode}
-\cs_new:Npn \@@_to_scientific:w \s_@@ \@@_chk:w #1#2#3 ;
+\group_begin:
+\char_set_catcode_other:N E
+\tl_to_lowercase:n
{
- \if_meaning:w 2 #2 \exp_after:wN - \tex_romannumeral:D -`0 \fi:
- \if_case:w #1 \exp_stop_f:
- \@@_case_return:nw { \exp_after:wN 0 }
- \or: \exp_after:wN \@@_to_scientific_normal:wnnnnn
- \or:
- \@@_case_use:nw
- {
- \@@_invalid_operation:Nnw
- \c_@@_scientific_inf_tl { fp_to_scientific }
- }
- \or:
- \@@_case_use:nw
- { \@@_invalid_operation:Nnw 0 { fp_to_scientific } }
- \fi:
- \s_@@ \@@_chk:w #1 #2 #3 ; \prg_do_nothing:
- }
-\cs_new:Npn \@@_to_scientific_normal:wnnnnn
- \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ; \prg_do_nothing:
- {
- \if_int_compare:w #2 = \c_one
- \exp_after:wN \@@_to_scientific_normal:wNw
- \else:
- \exp_after:wN \@@_to_scientific_normal:wNw
- \exp_after:wN e
- \int_use:N \__int_eval:w #2 - \c_one
- \fi:
- ; #3 #4 #5 #6 ;
+ \group_end:
+ \cs_new:Npn \@@_to_scientific:w \s_@@ \@@_chk:w #1#2
+ {
+ \if_meaning:w 2 #2 \exp_after:wN - \tex_romannumeral:D -`0 \fi:
+ \if_case:w #1 \exp_stop_f:
+ \@@_case_return:nw { 0 }
+ \or: \exp_after:wN \@@_to_scientific_normal:wnnnnn
+ \or:
+ \@@_case_use:nw
+ {
+ \@@_invalid_operation:nnw
+ {
+ \exp_after:wN 1
+ \exp_after:wN E
+ \int_use:N \c_@@_max_exponent_int
+ }
+ { fp_to_scientific }
+ }
+ \or:
+ \@@_case_use:nw
+ {
+ \@@_invalid_operation:nnw
+ { 0 }
+ { fp_to_scientific }
+ }
+ \fi:
+ \s_@@ \@@_chk:w #1 #2
+ }
+ \cs_new:Npn \@@_to_scientific_normal:wnnnnn
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ;
+ {
+ \if_int_compare:w #2 = \c_one
+ \exp_after:wN \@@_to_scientific_normal:wNw
+ \else:
+ \exp_after:wN \@@_to_scientific_normal:wNw
+ \exp_after:wN E
+ \int_use:N \__int_eval:w #2 - \c_one
+ \fi:
+ ; #3 #4 #5 #6 ;
+ }
}
\cs_new:Npn \@@_to_scientific_normal:wNw #1 ; #2#3;
{ \@@_trim_zeros:w #2.#3 ; #1 }
@@ -188,22 +194,6 @@
%
% \subsection{Decimal representation}
%
-% \begin{variable}{\c_@@_decimal_inf_tl}
-% Result of converting $\infty$ to a decimal representation: after
-% triggering an \enquote{invalid operation} exception,
-% \cs{fp_to_decimal:n} yields a~$1$ followed by $\ExplSyntaxOn
-% \int_use:N \c__fp_max_exponent_int$~$0$, larger than any finite
-% floating point number. Since the expanded token list is very long,
-% we use an \texttt{n}-type assignment.
-% \begin{macrocode}
-\tl_const:Nn \c_@@_decimal_inf_tl
- {
- \exp_after:wN \exp_after:wN \exp_after:wN 1
- \prg_replicate:nn \c_@@_max_exponent_int 0
- }
-% \end{macrocode}
-% \end{variable}
-%
% \begin{macro}[EXP]
% {\fp_to_decimal:N, \fp_to_decimal:c, \fp_to_decimal:n}
% All three public variants are based on the same \cs{@@_to_decimal:w}
@@ -219,7 +209,7 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP, aux]
+% \begin{macro}[aux, EXP]
% {
% \@@_to_decimal:w,
% \@@_to_decimal_normal:wnnnnn,
@@ -228,35 +218,45 @@
% }
% The structure is similar to \cs{@@_to_scientific:w}. Insert |-| for
% negative numbers. Zero gives $0$, $\pm\infty$ and \nan{} yield an
-% \enquote{invalid operation} exception. Normal numbers with an
-% exponent in the range $[1,15]$ have that number of digits before the
-% decimal separator: \enquote{decimate} them, and remove leading zeros
-% with \cs{__int_value:w}, then trim trailing zeros and dot. Normal
+% \enquote{invalid operation} exception; note that $\pm\infty$
+% produces a very large output, which we don't expand now since it
+% most likely won't be needed. Normal numbers with an exponent in the
+% range $[1,15]$ have that number of digits before the decimal
+% separator: \enquote{decimate} them, and remove leading zeros with
+% \cs{__int_value:w}, then trim trailing zeros and dot. Normal
% numbers with an exponent $16$ or larger have no decimal separator,
% we only need to add trailing zeros. When the exponent is
% non-positive, the result should be $0.\meta{zeros}\meta{digits}$,
% trimmed.
% \begin{macrocode}
-\cs_new:Npn \@@_to_decimal:w \s_@@ \@@_chk:w #1#2#3 ;
+\cs_new:Npn \@@_to_decimal:w \s_@@ \@@_chk:w #1#2
{
\if_meaning:w 2 #2 \exp_after:wN - \tex_romannumeral:D -`0 \fi:
\if_case:w #1 \exp_stop_f:
- \@@_case_return:nw { \exp_after:wN 0 }
+ \@@_case_return:nw { 0 }
\or: \exp_after:wN \@@_to_decimal_normal:wnnnnn
\or:
\@@_case_use:nw
{
- \@@_invalid_operation:Nnw
- \c_@@_decimal_inf_tl { fp_to_decimal }
+ \@@_invalid_operation:nnw
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN 1
+ \prg_replicate:nn \c_@@_max_exponent_int 0
+ }
+ { fp_to_decimal }
}
\or:
\@@_case_use:nw
- { \@@_invalid_operation:Nnw 0 { fp_to_decimal } }
+ {
+ \@@_invalid_operation:nnw
+ { 0 }
+ { fp_to_decimal }
+ }
\fi:
- \s_@@ \@@_chk:w #1 #2 #3 ; \prg_do_nothing:
+ \s_@@ \@@_chk:w #1 #2
}
\cs_new:Npn \@@_to_decimal_normal:wnnnnn
- \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ; \prg_do_nothing:
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ;
{
\int_compare:nNnTF {#2} > \c_zero
{
@@ -309,14 +309,12 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP, aux]{\@@_to_tl:w, \@@_to_tl_normal:nnnnn}
+% \begin{macro}[aux, EXP]{\@@_to_tl:w, \@@_to_tl_normal:nnnnn}
% A structure similar to \cs{@@_to_scientific:w} and
% \cs{@@_to_decimal:w}, but without the \enquote{invalid operation}
% exception. First filter special cases. We express normal numbers
% in decimal notation if the exponent is in the range $[-2,16]$, and
-% otherwise use scientific notation. The weird \cs{prg_do_nothing:}
-% is needed because the \texttt{decimal} and \texttt{scientific}
-% auxiliaries we use expect it.
+% otherwise use scientific notation.
% \begin{macrocode}
\cs_new:Npn \@@_to_tl:w \s_@@ \@@_chk:w #1#2
{
@@ -324,11 +322,11 @@
\if_case:w #1 \exp_stop_f:
\@@_case_return:nw { 0 }
\or: \exp_after:wN \@@_to_tl_normal:nnnnn
- \or: \@@_case_return:nw { inf }
- \else: \@@_case_return:nw { nan }
+ \or: \@@_case_return:nw { \tl_to_str:n {inf} }
+ \else: \@@_case_return:nw { \tl_to_str:n {nan} }
\fi:
}
-\cs_new:Npn \@@_to_tl_normal:nnnnn #1#2 ;
+\cs_new:Npn \@@_to_tl_normal:nnnnn #1
{
\if_int_compare:w #1 > \c_sixteen
\exp_after:wN \@@_to_scientific_normal:wnnnnn
@@ -341,24 +339,29 @@
\exp_after:wN \@@_to_decimal_normal:wnnnnn
\fi:
\fi:
- \s_@@ \@@_chk:w 1 0 {#1} #2 ; \prg_do_nothing:
+ \s_@@ \@@_chk:w 1 0 {#1}
}
% \end{macrocode}
% \end{macro}
%
% \subsection{Formatting}
%
-% ^^A todo
+% This is not implemented yet, as it is not yet clear what a correct
+% interface would be, for this kind of structured conversion from a
+% floating point (or other types of variables) to a string. Ideas
+% welcome.
%
% \subsection{Convert to dimension or integer}
%
% \begin{macro}[EXP]{\fp_to_dim:N, \fp_to_dim:c, \fp_to_dim:n}
% These three public functions rely on \cs{fp_to_decimal:n}
-% internally.
+% internally. We make sure to produce |pt| with category other.
% \begin{macrocode}
-\cs_new:Npn \fp_to_dim:N #1 { \fp_to_decimal:N #1 pt }
+\cs_new:Npx \fp_to_dim:N #1
+ { \exp_not:N \fp_to_decimal:N #1 \tl_to_str:n {pt} }
\cs_generate_variant:Nn \fp_to_dim:N { c }
-\cs_new:Npn \fp_to_dim:n #1 { \fp_to_decimal:n {#1} pt }
+\cs_new:Npx \fp_to_dim:n #1
+ { \exp_not:N \fp_to_decimal:n {#1} \tl_to_str:n {pt} }
% \end{macrocode}
% \end{macro}
%
@@ -385,7 +388,7 @@
\cs_new:Npn \@@_to_int:w #1;
{
\exp_after:wN \@@_to_decimal:w \tex_romannumeral:D -`0
- \@@_round:Nwn \@@_round_to_nearest:NNN #1; { 0 } \prg_do_nothing:
+ \@@_round:Nwn \@@_round_to_nearest:NNN #1; { 0 }
}
% \end{macrocode}
% \end{macro}
@@ -400,14 +403,12 @@
% \@@_from_dim_ii:wNNnnnnnn,
% \@@_from_dim_iii:wnnnnwN,
% }
-% The dimension expression (which can in fact be a glue expression)
-% is evaluated, converted to a number (\emph{i.e.}, expressed in
-% scaled points), then multiplied by $2^{-16} = 0.0000152587890625$
-% to give a value expressed in points. We use the auxiliary function
-% \begin{quote}
-% \cs{@@_mul_npos:Nnwnw} \meta{sign} \newline
-% ~~\Arg{exp_1} \meta{body_1} |;| \Arg{exp_2} \meta{body_2} |;|
-% \end{quote}
+% The dimension expression (which can in fact be a glue expression) is
+% evaluated, converted to a number (\emph{i.e.}, expressed in scaled
+% points), then multiplied by $2^{-16} = 0.0000152587890625$ to give a
+% value expressed in points. The auxiliary \cs{@@_mul_npos_o:Nww}
+% expects the desired \meta{final sign} and two floating point
+% operands (of the form \cs{s_@@} \ldots{} |;|) as arguments.
% \begin{macrocode}
\cs_new:Npn \dim_to_fp:n #1
{
@@ -417,8 +418,7 @@
\cs_new:Npn \@@_from_dim_test:N #1
{
\if_meaning:w 0 #1
- \exp_after:wN \@@_use_i_until_s:nw
- \exp_after:wN \c_zero_fp
+ \@@_case_return:nw \c_zero_fp
\else:
\if_meaning:w - #1
\exp_after:wN \@@_from_dim:Nw
@@ -440,8 +440,9 @@
{ \@@_from_dim_iii:wnnnnwN #1 {#2#300} {0000} ; }
\cs_new:Npn \@@_from_dim_iii:wnnnnwN #1; #2#3#4#5#6; #7
{
- \@@_mul_npos:Nnwnw #7 {#5} #1 ;
- {-4} {1525} {8789} {0625} {0000} ;
+ \@@_mul_npos_o:Nww #7
+ \s_@@ \@@_chk:w 1 #7 {#5} #1 ;
+ \s_@@ \@@_chk:w 1 0 {-4} {1525} {8789} {0625} {0000} ;
}
% \end{macrocode}
% \end{macro}
@@ -459,9 +460,12 @@
% \end{macro}
%
% \begin{macro}[EXP]{\fp_abs:n}
-% Trivial but useful.
+% Trivial but useful. See the implementation of \cs{fp_add:Nn} for an
+% explanation of why to use \cs{@@_parse:n}, namely, for better error
+% reporting.
% \begin{macrocode}
-\cs_new:Npn \fp_abs:n #1 { \fp_to_decimal:n { abs ( #1 ) } }
+\cs_new:Npn \fp_abs:n #1
+ { \fp_to_decimal:n { abs \@@_parse:n {#1} } }
% \end{macrocode}
% \end{macro}
%
@@ -473,4 +477,4 @@
%
% \PrintChanges
%
-% \PrintIndex \ No newline at end of file
+% \PrintIndex