summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3int.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3int.dtx150
1 files changed, 73 insertions, 77 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
index 89695862b2f..0719e0e86df 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3int.dtx 2551 2011-08-11 22:40:53Z bruno $
+\GetIdInfo$Id: l3int.dtx 2600 2011-08-16 22:31:24Z bruno $
{L3 Experimental integers}
%</driver|package>
%<*driver>
@@ -631,16 +631,6 @@
% with category code $11$ (letter).
% \end{function}
%
-% \begin{function}[EXP]{\int_to_symbol:n}
-% \begin{syntax}
-% \cs{int_to_symbol:n} \Arg{integer expression}
-% \end{syntax}
-% Calculates the value of the \meta{integer expression} and places
-% the symbol representation of the result in the input stream. The
-% list of symbols used is equivalent to \LaTeXe{}'s \cs{@fnsymbol}
-% set.
-% \end{function}
-%
% \section{Converting from other formats to integers}
%
% \begin{function}[EXP]{\int_from_alph:n}
@@ -1613,89 +1603,95 @@
%
% \begin{macro}{\int_to_base:nn}
% \UnitTested
-% \begin{macro}[aux]{\int_to_base_aux:nnn}
+% \begin{macro}[aux]{\int_to_base_aux_i:nn,
+% \int_to_base_aux_ii:nnN,\int_to_base_aux_iii:nnnN}
% \begin{macro}[int]{\int_to_letter:n}
% \UnitTested
% Converting from base ten (|#1|) to a second base (|#2|) starts with
-% a simple sign check. As the input is base $10$ \TeX{} can then
-% do the actual work with the sign itself.
+% computing |#1|: if it is a complicated calculation, we shouldn't
+% perform it twice. Then check the sign, store it, either \texttt{-}
+% or \cs{c_empty_tl}, and feed the absolute value to the next auxiliary
+% function.
% \begin{macrocode}
-\cs_new:Npn \int_to_base:nn #1#2
+\cs_new:Npn \int_to_base:nn #1
+ { \exp_args:Nf \int_to_base_aux_i:nn { \int_eval:n {#1} } }
+\cs_new:Npn \int_to_base_aux_i:nn #1#2
{
\int_compare:nNnTF {#1} < \c_zero
- {
- -
- \exp_args:Nnf \int_to_base_aux:nnn
- { } { \int_eval:n { 0 - ( #1 ) } } {#2}
- }
- {
- \exp_args:Nnf \int_to_base_aux:nnn
- { } { \int_eval:n {#1} } {#2}
- }
-}
+ { \exp_args:No \int_to_base_aux_ii:nnN { \use_none:n #1 } {#2} - }
+ { \int_to_base_aux_ii:nnN {#1} {#2} \c_empty_tl }
+ }
% \end{macrocode}
% Here, the idea is to provide a recursive system to deal with the
-% input. The output is build up as argument |#1|, which is why it
-% starts off empty in the above. At each pass, the value in |#2| is
-% checked to see if it is less than the new base (|#3|). If it is
-% the it is converted directly and the rest of the output is added in.
+% input. The output is built up after the end of the function.
+% At each pass, the value in |#1| is checked to see if it is less
+% than the new base (|#2|). If it is, then it is converted directly,
+% putting the sign back in front.
% On the other hand, if the value to convert is greater than or equal
% to the new base then the modulus and remainder values are found. The
-% modulus is converted to a symbol and the remainder is carried forward
-% to the next round.
+% modulus is converted to a symbol and put on the right,
+% and the remainder is carried forward to the next round.
% \begin{macrocode}
-\cs_new:Npn \int_to_base_aux:nnn #1#2#3 {
- \int_compare:nNnTF {#2} < {#3}
- {
- \int_to_letter:n {#2}
- #1
- }
- {
- \exp_args:Nff \int_to_base_aux:nnn
- {
- \int_to_letter:n { \int_mod:nn {#2} {#3} }
- #1
- }
- { \int_div_truncate:nn {#2} {#3} }
- {#3}
- }
+\cs_new:Npn \int_to_base_aux_ii:nnN #1#2#3
+ {
+ \int_compare:nNnTF {#1} < {#2}
+ { \exp_last_unbraced:Nf #3 { \int_to_letter:n {#1} } }
+ {
+ \exp_args:Nf \int_to_base_aux_iii:nnnN
+ { \int_to_letter:n { \int_mod:nn {#1} {#2} } }
+ {#1}
+ {#2}
+ #3
+ }
+ }
+\cs_new:Npn \int_to_base_aux_iii:nnnN #1#2#3#4
+ {
+ \exp_args:Nf \int_to_base_aux_ii:nnN
+ { \int_div_truncate:nn {#2} {#3} }
+ {#3}
+ #4
+ #1
}
% \end{macrocode}
% Convert to a letter only if necessary, otherwise simply return the
-% value unchanged.
+% value unchanged. It would be cleaner to use \cs{prg_case_int:nnn},
+% but in our case, the cases are contiguous, so it is forty times faster
+% to use the \cs{if_case:w} primitive. The first \cs{exp_after:wN}
+% expands the conditional, jumping to the correct case, the second one
+% expands after the resulting character to close the conditional.
% \begin{macrocode}
\cs_new:Npn \int_to_letter:n #1
{
- \prg_case_int:nnn { #1 - 9 }
- {
- { 1 } { A }
- { 2 } { B }
- { 3 } { C }
- { 4 } { D }
- { 5 } { E }
- { 6 } { F }
- { 7 } { G }
- { 8 } { H }
- { 9 } { I }
- { 10 } { J }
- { 11 } { K }
- { 12 } { L }
- { 13 } { M }
- { 14 } { N }
- { 15 } { O }
- { 16 } { P }
- { 17 } { Q }
- { 18 } { R }
- { 19 } { S }
- { 20 } { T }
- { 21 } { U }
- { 22 } { V }
- { 23 } { W }
- { 24 } { X }
- { 25 } { Y }
- { 26 } { Z }
- }
- {#1}
+ \exp_after:wN \exp_after:wN
+ \if_case:w \int_eval:w #1 - \c_ten \int_eval_end:
+ A
+ \or: B
+ \or: C
+ \or: D
+ \or: E
+ \or: F
+ \or: G
+ \or: H
+ \or: I
+ \or: J
+ \or: K
+ \or: L
+ \or: M
+ \or: N
+ \or: O
+ \or: P
+ \or: Q
+ \or: R
+ \or: S
+ \or: T
+ \or: U
+ \or: V
+ \or: W
+ \or: X
+ \or: Y
+ \or: Z
+ \else: #1
+ \fi:
}
% \end{macrocode}
%\end{macro}