[latex3-commits] [git/LaTeX3-latex3-latex3] master: Change fp random implementation (be4ade7)
Bruno Le Floch
bruno at le-floch.fr
Sun May 6 16:13:51 CEST 2018
Repository : https://github.com/latex3/latex3
On branch : master
Link : https://github.com/latex3/latex3/commit/be4ade7818d593a77cf9c9523e9c356a88af9ada
>---------------------------------------------------------------
commit be4ade7818d593a77cf9c9523e9c356a88af9ada
Author: Bruno Le Floch <bruno at le-floch.fr>
Date: Sat May 5 18:54:34 2018 -0400
Change fp random implementation
Seeds with the same parity were (often) producing the same sequence
of parities for the 16th digit of successive rand(), for instance.
>---------------------------------------------------------------
be4ade7818d593a77cf9c9523e9c356a88af9ada
l3kernel/l3fp-random.dtx | 396 +++++++++++++++++---------------------
l3kernel/testfiles/m3rand001.tlg | 78 ++++----
2 files changed, 211 insertions(+), 263 deletions(-)
diff --git a/l3kernel/l3fp-random.dtx b/l3kernel/l3fp-random.dtx
index 4deabe4..d259099 100644
--- a/l3kernel/l3fp-random.dtx
+++ b/l3kernel/l3fp-random.dtx
@@ -199,7 +199,12 @@
% ensures that the number obtained before the shift and division is at
% most $2^{17}(2^{14}-1)+(2^{17}-1)=\cs{c_max_int}$. The
% non-uniformity is at most of order $2^{17}/2^{42} = 2^{-25}$.
-% \item Otherwise, split $R=R_2\times 2^{28}+R_1\times 2^{14}+R_0$,
+% \item Since it is not clear that the plan outlined in the following
+% paragraph has good uniformity, we implement large ranges directly in
+% terms of the floating point |randint|.
+%
+% Earlier plan: \enquote{Otherwise,
+% split $R=R_2\times 2^{28}+R_1\times 2^{14}+R_0$,
% precompute $R_{21}=R_2\times 2^{14}+R_1$ and
% $R_{10}=R_1\times 2^{14}+R_0$ and $Z = X_1\times 2^{14}+Y_1$. Then
% compute on the one hand
@@ -210,133 +215,94 @@
% \operatorname{ediv}(R_{10}\times Y,2^{28}),2^{14})$ then sum them
% (this may give $2^{31}$, an overflow). If the result is greater
% than $\meta{max}$ (in particular if it overflows) then replace it by
-% $\meta{min}$.
+% $\meta{min}$.}
% \item To get a floating point number in $[0,1)$ just call the
% $R=10000\leq 2^{17}$ procedure above to produce four blocks of four
% digits.
-% \item To get an integer floating point number in a small range
-% $R\leq 2^{17}$ use the above simplified algorithm. If the range is
-% bigger (it can be up to $2\times 10^{16}-1$), work with fixed-point
-% numbers: get six times four digits to build a fixed point number,
-% multiply by $R$ and add $\meta{min}$.
+% \item To get an integer floating point number in a range (whose size
+% can be up to $2\times 10^{16}-1$), work with fixed-point numbers:
+% get six times four digits to build a fixed point number, multiply by
+% $R$ and add $\meta{min}$. This requires some care because
+% \pkg{l3fp-extended} only supports non-negative numbers.
% \end{itemize}
-% This is strategy is not yet implemented at all.
%
-% \begin{macro}[EXP]{\@@_rand_uniform:}
-% \begin{variable}
-% {
-% \c_@@_rand_size_int,
-% \c_@@_rand_four_int,
-% \c_@@_rand_eight_int,
-% }
-% The \cs{tex_uniformdeviate:D} primitive gives a pseudo-random
-% integer in a range $[0,n-1]$ of the user's choice. This number is
-% meant to be uniformly distributed, but is produced by rescaling a
-% uniform pseudo-random integer in $[0,2^{28}-1]$. For instance,
-% setting~$n$ to (any multiple of) $2^{29}$ gives only even values.
-% Thus it is only safe to call \cs{tex_uniformdeviate:D} with
-% argument $2^{28}$. This integer is also used in the implementation
-% of \cs{int_rand:nn}. We also use variants of this number
-% rounded down to multiples of $10^4$ and $10^8$.
+% \begin{variable}{\c_@@_rand_critical_int}
+% Constant equal to $2^{17}$, the maximal size of a range that
+% \cs{int_range:nn} can do with its \enquote{simple} algorithm.
% \begin{macrocode}
- \cs_new:Npn \@@_rand_uniform:
- { \tex_uniformdeviate:D \c_@@_rand_size_int }
- \int_const:Nn \c_@@_rand_size_int { 268 435 456 }
- \int_const:Nn \c_@@_rand_four_int { 268 430 000 }
- \int_const:Nn \c_@@_rand_eight_int { 200 000 000 }
+ \int_const:Nn \c_@@_rand_critical_int { 13 1072 }
% \end{macrocode}
% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_randint:nn}
+% Used in an integer expression, \cs{@@_randint:nn} \Arg{min}
+% |{|$R$|}| gives a random number
+% $\lfloor(R\operatorname{random}(2^{14}) +
+% \operatorname{random}(R))/2^{14}\rfloor$. that is between
+% \meta{min} and $\meta{min}+R-1$ inclusive.
+% \begin{macrocode}
+ \cs_new:Npn \@@_randint:nn #1#2
+ {
+ #1 + (#2 * \tex_uniformdeviate:D 1 6384
+ + \tex_uniformdeviate:D #2 - 8192 ) / 16384
+ }
+% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\@@_rand_myriads:n}
% \begin{macro}[EXP]
-% {
-% \@@_rand_myriads_loop:nn,
-% \@@_rand_myriads_get:w,
-% \@@_rand_myriads_last:,
-% \@@_rand_myriads_last:w,
-% }
-% Used as \cs{@@_rand_myriads:n} |{XXX}| with one input character per
-% block of four digit we want. Given a pseudo-random integer from the
-% primitive, we extract $2$ blocks of digits if possible, namely if
-% the integer is less than $2\times 10^8$. If that's not possible,
-% we try to extract $1$~block, which succeeds in the range $[2\times
-% 10^8, 26843\times 10^4)$. For the $5456$ remaining possible values
-% we just throw away the random integer and get a new one. Depending
-% on whether we got $2$, $1$, or~$0$ blocks, remove the same number of
-% characters from the input stream with \cs{use_i:nnn}, \cs{use_i:nn}
-% or nothing.
+% {\@@_rand_myriads:n, \@@_rand_myriads_loop:w, \@@_rand_myriads_get:w}
+% Used as \cs{@@_rand_myriads:n} |{XXX}| with one letter |X|
+% (specifically) per block of four digit we want; it expands to |;|
+% followed by the requested number of brace groups, each containing
+% four (pseudo-random) digits. Digits are produced as a random number
+% in $[10000,19999]$ for the usual reason of preserving leading zeros.
% \begin{macrocode}
\cs_new:Npn \@@_rand_myriads:n #1
+ { \@@_rand_myriads_loop:w #1 \prg_break: X \prg_break_point: ; }
+ \cs_new:Npn \@@_rand_myriads_loop:w #1 X
{
- \@@_rand_myriads_loop:nn #1
- { ? \use_i_delimit_by_q_stop:nw \@@_rand_myriads_last: }
- { ? \use_none_delimit_by_q_stop:w } \q_stop
- }
- \cs_new:Npn \@@_rand_myriads_loop:nn #1#2
- {
- \use_none:n #2
+ #1
\exp_after:wN \@@_rand_myriads_get:w
- \int_value:w \@@_rand_uniform: ; {#1}{#2}
- }
- \cs_new:Npn \@@_rand_myriads_get:w #1 ;
- {
- \if_int_compare:w #1 < \c_@@_rand_eight_int
- \exp_after:wN \use_none:n
- \int_value:w \@@_int_eval:w
- \c_@@_rand_eight_int + #1 \@@_int_eval_end:
- \exp_after:wN \use_i:nnn
- \else:
- \if_int_compare:w #1 < \c_@@_rand_four_int
- \exp_after:wN \use_none:nnnnn
- \int_value:w \@@_int_eval:w
- \c_@@_rand_four_int + #1 \@@_int_eval_end:
- \exp_after:wN \exp_after:wN \exp_after:wN \use_i:nn
- \fi:
- \fi:
- \@@_rand_myriads_loop:nn
- }
- \cs_new:Npn \@@_rand_myriads_last:
- {
- \exp_after:wN \@@_rand_myriads_last:w
- \int_value:w \@@_rand_uniform: ;
- }
- \cs_new:Npn \@@_rand_myriads_last:w #1 ;
- {
- \if_int_compare:w #1 < \c_@@_rand_four_int
- \exp_after:wN \use_none:nnnnn
- \int_value:w \@@_int_eval:w
- \c_@@_rand_four_int + #1 \@@_int_eval_end:
- \else:
- \exp_after:wN \@@_rand_myriads_last:
- \fi:
+ \int_value:w \@@_int_eval:w
+ \@@_randint:nn { 10000 } { 10000 }
+ \@@_rand_myriads_loop:w
}
+ \cs_new:Npn \@@_rand_myriads_get:w 1 #1 ; { ; {#1} }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \subsection{Random floating point}
%
-% \begin{macro}[EXP]{\@@_rand_o:Nw}
-% \begin{macro}[EXP]{\@@_rand_o:, \@@_rand_o:w}
+% \begin{macro}[EXP]{\@@_rand_o:Nw, \@@_rand_o:w}
% First we check that |random| was called without argument. Then get
-% four blocks of four digits.
+% four blocks of four digits and convert that fixed point number to a
+% floating point number (this correctly sets the exponent). This has
+% a minor bug: if all of the random numbers are zero then the result
+% is correctly~$0$ but it raises the \texttt{underflow} flag; it
+% should not do that.
% \begin{macrocode}
\cs_new:Npn \@@_rand_o:Nw ? #1 @
{
\tl_if_empty:nTF {#1}
- { \@@_rand_o: }
+ {
+ \exp_after:wN \@@_rand_o:w
+ \exp:w \exp_end_continue_f:w
+ \@@_rand_myriads:n { XXXX } { 0000 } { 0000 } ; 0
+ }
{
\__kernel_msg_expandable_error:nnnnn
{ kernel } { fp-num-args } { rand() } { 0 } { 0 }
\exp_after:wN \c_nan_fp
}
}
- \cs_new:Npn \@@_rand_o:
- { \@@_parse_o:n { . \@@_rand_myriads:n { xxxx } } }
+ \cs_new:Npn \@@_rand_o:w ;
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN 0
+ \int_value:w \@@_int_eval:w \c_zero \@@_fixed_to_float_o:wN
+ }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \subsection{Random integer}
%
@@ -346,33 +312,31 @@
% \@@_randint_default:w,
% \@@_randint_badarg:w,
% \@@_randint_o:w,
-% \@@_randint_e:wnn,
-% \@@_randint_e:wwNnn,
-% \@@_randint_e:wwwNnn,
-% \@@_randint_narrow_e:nnnn,
-% \@@_randint_wide_e:nnnn,
-% \@@_randint_wide_e:wnnn,
+% \@@_randint_auxi_o:ww,
+% \@@_randint_auxii:wn,
+% \@@_randint_auxiii_o:ww,
+% \@@_randint_auxiv_o:ww,
+% \@@_randint_auxv_o:w,
% }
% Enforce that there is one argument (then add first argument~$1$)
-% or two arguments. Enforce that they are integers in
-% $(-10^{16},10^{16})$ and ordered. We distinguish narrow ranges
-% (less than $2^{28}$) from wider ones.
-%
-% For narrow ranges, compute the number~$n$ of possible outputs as
-% an integer using \cs{fp_to_int:n}, and reduce a pseudo-random
-% $28$-bit integer~$r$ modulo~$n$. On its own, this is not uniform
-% when $[0,2^{28}-1]$ does not divide evenly into intervals of
-% size~$n$. The auxiliary \cs{@@_randint_e:wwwNnn} discards the
-% pseudo-random integer if it lies in an incomplete interval, and
-% repeats.
-%
-% For wide ranges we use the same code except for the last eight
-% digits which use \cs{@@_rand_myriads:n}. It is not safe to
-% combine the first digits with the last eight as a single string of
-% digits, as this may exceed $16$~digits and be rounded. Instead,
-% we first add the first few digits (times $10^8$) to the lower
-% bound. The result is compared to the upper bound and the process
-% repeats if needed.
+% or two arguments. Call \cs{@@_randint_badarg:w} on each; this
+% function inserts |1| \cs{exp_stop_f:} to end the \cs{if_case:w}
+% statement if either the argument is not an integer or if its
+% absolute value is $\geq 10^{16}$. Also bail out if
+% \cs{@@_compare_back:ww} yields~|1|, meaning that the bounds are
+% not in the right order. Otherwise an auxiliary converts each
+% argument times $10^{-16}$ (hence the shift in exponent) to a
+% $24$-digit fixed point number (see \pkg{l3fp-extended}).
+% Then compute the number of choices, $\meta{max}+1-\meta{min}$.
+% Create a random $24$-digit fixed-point number with
+% \cs{@@_rand_myriads:n}, then use a fused multiply-add instruction
+% to multiply the number of choices to that random number and add it
+% to \meta{min}. Then truncate to $16$ digits (namely select the
+% integer part of $10^{16}$ times the result) before converting back
+% to a floating point number (\cs{@@_sanitize:Nw} takes care of zero).
+% To avoid issues with negative numbers, add $1$ to all fixed point
+% numbers (namely $10^{16}$ to the integers they represent), except
+% of course when it is time to convert back to a float.
% \begin{macrocode}
\cs_new:Npn \@@_randint_o:Nw ?
{
@@ -387,7 +351,7 @@
{
\if_meaning:w 1 #1
\if_int_compare:w
- \use_i_delimit_by_q_stop:nw #3 \q_stop > \c_@@_prec_int
+ \@@_use_i_until_s:nw #3 ; > \c_@@_prec_int
1 \exp_stop_f:
\fi:
\fi:
@@ -399,9 +363,9 @@
\if_case:w
\@@_randint_badarg:w #1;
\@@_randint_badarg:w #2;
- \fp_compare:nNnTF { #1; } > { #2; } { 1 } { 0 } \exp_stop_f:
- \exp_after:wN \exp_after:wN \exp_after:wN \@@_randint_e:wnn
- \@@_parse:n { #2; - #1; } { #1; } { #2; }
+ \if:w 1 \@@_compare_back:ww #2; #1; 1 \exp_stop_f: \fi:
+ 0 \exp_stop_f:
+ \@@_randint_auxi_o:ww #1; #2;
\or:
\@@_invalid_operation_tl_o:ff
{ randint } { \@@_array_to_clist:n { #1; #2; } }
@@ -409,134 +373,118 @@
\fi:
\exp_after:wN \exp_end:
}
- \cs_new:Npn \@@_randint_e:wnn #1;
+ \cs_new:Npn \@@_randint_auxi_o:ww #1 ; #2 ; #3 \exp_end:
{
- \exp_after:wN \@@_randint_e:wwNnn
- \int_value:w \@@_rand_uniform: \exp_after:wN ;
- \exp:w \exp_end_continue_f:w
- \fp_compare:nNnTF { #1 ; } < \c_@@_rand_size_int
- { \fp_to_int:n { #1 ; + 1 } ; \@@_randint_narrow_e:nnnn }
- {
- \fp_to_int:n { floor(#1 ; * 1e-8 + 1) } ;
- \@@_randint_wide_e:nnnn
- }
+ \fi:
+ \@@_randint_auxii:wn #2 ;
+ { \@@_randint_auxii:wn #1 ; \@@_randint_auxiii_o:ww }
}
- \cs_new:Npn \@@_randint_e:wwNnn #1 ; #2 ;
+ \cs_new:Npn \@@_randint_auxii:wn \s_@@ \@@_chk:w 1#1#2#3 ;
{
- \exp_after:wN \@@_randint_e:wwwNnn
- \int_value:w \int_mod:nn {#1} {#2} ; #1 ; #2 ;
+ \exp_after:wN \@@_ep_to_fixed:wwn
+ \int_value:w \@@_int_eval:w
+ #2 - \c_@@_prec_int , #3 {0000} {0000} ;
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \use_i:nnnn
+ \exp_after:wN \@@_fixed_add_one:wN
+ \fi:
+ \exp_after:wN \@@_fixed_sub:wwn \c_@@_one_fixed_tl
+ }
+ \@@_fixed_continue:wn
}
- \cs_new:Npn \@@_randint_e:wwwNnn #1 ; #2 ; #3 ; #4
+ \cs_new:Npn \@@_randint_auxiii_o:ww #1 ; #2 ;
{
- \int_compare:nNnTF { #2 - #1 + #3 } > \c_@@_rand_size_int
- {
- \exp_after:wN \@@_randint_e:wwNnn
- \int_value:w \@@_rand_uniform: ; #3 ; #4
- }
- { #4 {#1} {#3} }
+ \@@_fixed_add:wwn #2 ;
+ {0000} {0000} {0000} {0001} {0000} {0000} ;
+ \@@_fixed_sub:wwn #1 ;
+ {
+ \exp_after:wN \use_i:nn
+ \exp_after:wN \@@_fixed_mul_add:wwwn
+ \exp:w \exp_end_continue_f:w \@@_rand_myriads:n { XXXXXX } ;
+ }
+ #1 ;
+ \@@_randint_auxiv_o:ww
+ #2 ;
+ \@@_randint_auxv_o:w #1 ; @
}
- \cs_new:Npn \@@_randint_narrow_e:nnnn #1#2#3#4
- { \@@_parse_o:n { #3 + #1 } \exp:w }
- \cs_new:Npn \@@_randint_wide_e:nnnn #1#2#3#4
+ \cs_new:Npn \@@_randint_auxiv_o:ww #1#2#3#4#5 ; #6#7#8#9
{
- \exp_after:wN \exp_after:wN
- \exp_after:wN \@@_randint_wide_e:wnnn
- \@@_parse:n { #3 + #1e8 + \@@_rand_myriads:n { xx } }
- {#2} {#3} {#4}
+ \if_int_compare:w
+ \if_int_compare:w #1#2 > #6#7 \exp_stop_f: 1 \else:
+ \if_int_compare:w #1#2 < #6#7 \exp_stop_f: - \fi: \fi:
+ #3#4 > #8#9 \exp_stop_f:
+ \@@_use_i_until_s:nw
+ \fi:
+ \@@_randint_auxv_o:w {#1}{#2}{#3}{#4}#5
}
- \cs_new:Npn \@@_randint_wide_e:wnnn #1 ; #2#3#4
+ \cs_new:Npn \@@_randint_auxv_o:w #1#2#3#4#5 ; #6 @
{
- \fp_compare:nNnTF { #1 ; } > {#4}
- {
- \exp_after:wN \@@_randint_e:wwNnn
- \int_value:w \@@_rand_uniform: ; #2 ;
- \@@_randint_wide_e:nnnn {#3} {#4}
- }
- { \@@_exp_after_o:w #1 ; \exp:w }
+ \exp_after:wN \@@_sanitize:Nw
+ \int_value:w
+ \if_int_compare:w #1 < 10000 \exp_stop_f:
+ 2
+ \else:
+ 0
+ \exp_after:wN \exp_after:wN
+ \exp_after:wN \@@_reverse_args:Nww
+ \fi:
+ \exp_after:wN \@@_fixed_sub:wwn \c_@@_one_fixed_tl
+ {#1} {#2} {#3} {#4} {0000} {0000} ;
+ {
+ \exp_after:wN \exp_stop_f:
+ \int_value:w \@@_int_eval:w \c_@@_prec_int
+ \@@_fixed_to_float_o:wN
+ }
+ 0
+ \exp:w \exp_after:wN \exp_end:
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\int_rand:nn}
-% \begin{macro}{\@@_randint:ww}
-% \begin{macro}{\@@_randint_narrow:n}
-% \begin{macro}{\@@_randint_narrow:nn}
-% \begin{macro}{\@@_randint_narrow:nnn}
+% \begin{macro}{\int_rand:nn, \@@_randint:ww}
% Evaluate the argument and filter out the case where the lower
% bound~|#1| is more than the upper bound~|#2|. Then determine
-% whether the range is narrower than \cs{c_@@_rand_size_int}; |#2-#1|
-% may overflow for very large positive~|#2| and negative~|#1|. If the
-% range is wide, use slower code from \pkg{l3fp}. If the range is
-% narrow, call \cs{@@_randint_narrow:n} \Arg{choices} where
+% whether the range is narrower than \cs{c_@@_rand_critical_int};
+% |#2-#1| may overflow for very large positive~|#2| and negative~|#1|.
+% If the range is wide, use slower code from \pkg{l3fp}. If the range
+% is narrow, call \cs{@@_randint:nn} |{#1}| \Arg{choices} where
% \meta{choices} is the number of possible outcomes.
-%
-% One option then would be to reduce a random number modulo
-% \meta{choices}, but the low-order bits of random numbers provided by
-% the primitive have poor randomness: empirical tests indicate that
-% taking random numbers modulo~$2$ gives only two possible sequences
-% of bits depending on the seed's parity. Instead, fit in the output
-% range $[0,\cs{c_@@_rand_size_int}-1]$ of the random number generator
-% \meta{choices} equal-size intervals of maximum possible size
-% (obtained using \cs{int_div_truncate:nn}). Given a random number,
-% divide it by the size to determine which interval it falls into; if
-% it is beyond \meta{choices}, try another random number.
% \begin{macrocode}
\cs_new:Npn \int_rand:nn #1#2
{
- \exp_after:wN \@@_randint:ww
- \int_value:w \int_eval:n {#1} \exp_after:wN ;
- \int_value:w \int_eval:n {#2} ;
- }
- \cs_new:Npn \@@_randint:ww #1; #2;
- {
- \int_compare:nNnTF {#1} > {#2}
+ \int_eval:n
{
- \__kernel_msg_expandable_error:nnnn
- { kernel } { randint-backward-range } {#1} {#2}
- \@@_randint:ww #2; #1;
- }
- {
- \int_compare:nNnTF {#1} > 0
- { \int_compare:nNnTF { #2 - #1 } < \c_@@_rand_size_int }
- { \int_compare:nNnTF {#2} < { #1 + \c_@@_rand_size_int } }
- {
- \int_eval:n
- {
- #1 +
- \exp_args:Nf \@@_randint_narrow:n
- { \int_eval:n { #2 - #1 + 1 } }
- }
- }
- { \fp_to_int:n { randint(#1,#2) } }
+ \exp_after:wN \@@_randint:ww
+ \int_value:w \int_eval:n {#1} \exp_after:wN ;
+ \int_value:w \int_eval:n {#2} ;
}
}
- \cs_new:Npn \@@_randint_narrow:n #1
- {
- \exp_args:Nf \@@_randint_narrow:nn
- { \int_div_truncate:nn \c_@@_rand_size_int {#1} } {#1}
- }
- \cs_new:Npn \@@_randint_narrow:nn #1
- {
- \exp_args:Nf \@@_randint_narrow:nnn
- {
- \int_div_truncate:nn
- { \tex_uniformdeviate:D \c_@@_rand_size_int } {#1}
- }
- {#1}
- }
- \cs_new:Npn \@@_randint_narrow:nnn #1#2#3
+ \cs_new:Npn \@@_randint:ww #1; #2;
{
- \int_compare:nNnTF {#1} < {#3}
- {#1}
- { \@@_randint_narrow:nn {#2} {#3} }
+ \if_int_compare:w #1 > #2 \exp_stop_f:
+ \__kernel_msg_expandable_error:nnnn
+ { kernel } { randint-backward-range } {#1} {#2}
+ \@@_randint:ww #2; #1;
+ \else:
+ \if_int_compare:w \@@_int_eval:w #2
+ \if_int_compare:w #1 > \c_zero
+ - #1 < \@@_int_eval:w
+ \else:
+ < \@@_int_eval:w #1 +
+ \fi:
+ \c_@@_rand_critical_int
+ \@@_int_eval_end:
+ \@@_randint:nn {#1}
+ { \@@_int_eval:w #2 - #1 + 1 \@@_int_eval_end: }
+ \else:
+ \fp_to_int:n { randint(#1,#2) }
+ \fi:
+ \fi:
}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
% End the initial conditional that ensures these commands are only
% defined in engines that support random numbers.
diff --git a/l3kernel/testfiles/m3rand001.tlg b/l3kernel/testfiles/m3rand001.tlg
index ff4d480..138d849 100644
--- a/l3kernel/testfiles/m3rand001.tlg
+++ b/l3kernel/testfiles/m3rand001.tlg
@@ -4,40 +4,40 @@ Author: Bruno Le Floch
============================================================
TEST 1: Random floating point number
============================================================
-0.6462368894354278
-0.9436367545979044
-0.4852789154091621
-0.177206678619497
-0.5709297441167938
+0.240735155533066
+0.5852214353430764
+0.7180176671856077
+0.3615756894278821
+0.4478174648957779
============================================================
============================================================
TEST 2: Random integer
============================================================
2
1
-2
1
+2
1
-9999999999999999
--9999999999999999
-9999999999999998
-9999999999999999
-9999999999999999
-444814453
-983095862
-958440641
-448535503
-361158142
-6698906031397161
-4488284872942466
-6862012124606703
-4745501327166187
-9558266238979667
--8367420653049596
--616799027378363
-1497734804749083
-6603444483764452
--9258032600444501
+-9999999999999999
+174462024
+43469076
+964237967
+281796922
+571531749
+647645817006079
+6227277400369880
+4448422924240445
+5041817501660381
+2577799052913806
+8570669930344415
+4534632579885364
+9640121450586277
+928036911121429
+-493197266565851
============================================================
============================================================
TEST 3: Random bad arguments
@@ -218,7 +218,7 @@ nan
nan
nan
nan
-1
+0
nan
nan
nan
@@ -226,52 +226,52 @@ nan
============================================================
TEST 4: Random integer in a range
============================================================
-|0|-1|0|1|0|1|0|0|-1|1|-1|0|1|1|0|
+|-1|1|-1|1|0|0|1|-1|1|0|1|1|-1|-1|1|
|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|-2147483647|
-|-2147483638|-2147483643|-2147483642|-2147483642|-2147483642|-2147483645|-2147483641|-2147483646|-2147483646|-2147483644|-2147483647|-2147483639|-2147483642|-2147483645|-2147483646|
-|-1383802119|1847464213|1896138077|1141097059|-1805716453|303683616|630789435|83660916|1553919714|2065890169|-143934675|-1879794472|-640520242|1146446601|-1026621466|
+|-2147483645|-2147483647|-2147483645|-2147483639|-2147483646|-2147483641|-2147483637|-2147483641|-2147483637|-2147483643|-2147483639|-2147483642|-2147483644|-2147483637|-2147483645|
+|-596602719|-440743317|1859629516|1035797053|-83292061|1733661836|-1455563191|-1354595511|1588647823|215900686|-1947340226|-1997076099|-1997696982|378940000|1354742325|
============================================================
============================================================
TEST 5: Random tl item
============================================================
||
|\A |\A |\A |\A |\A |\A |\A |\A |\A |\A |\A |\A |\A |\A |\A |
-|\A |\A | \B |\A | \B | \B | \B | \B | \B |\A | \B | \B | \B |\A | \B |
-|\C |\A |\C |\C |\A |{\B }|\A |{\B }|\C |{\B }|\A |\A |{\B }|\C |{\B }|
+| \B |\A |\A |\A | \B |\A |\A |\A | \B |\A | \B |\A |\A | \B |\A |
+|{\B }|{\B }|\C |\A |{\B }|\A |\A |\C |\A |{\B }|\C |\C |\A |{\B }|\A |
||||||||||||||||
||||||||||||||||
-| | | | | |||| | || | | ||
-| | | |\A |&|\A |##|##|##| |##|##|\A | |\A |
+| | || | |||| | | | || ||
+|\A |&| |&|&|##|&|&| |\A |##| |##|&| |
============================================================
============================================================
TEST 6: Random clist item
============================================================
||
-|\B |\A |\A |\B |\B |\B |\A |\B |\B |\A |\B |\B |\B |\A |\B |
-|{}|\A |\A |\A |\A |\A |\A |\A |\A | \B |\A |\A |{}|\A | ,|
+|\A |\B |\A |\B |\A |\A |\A |\B |\A |\B |\A |\A |\A |\B |\B |
+| ,|\A |\A | \B |{}|\A | ,|{}| \B | \B |\A |\A | ,| \B | \B |
||||||||||||||||
-| ,|| ,|| ,|| ,||||| ,|| ,||
-|,|,|##|,|,|\\|##|,|&|\\|\\|##|,|,|,|
+| ,| ,|| ,| ,| ,| ,| ,|| ,| ,| ,|| ,||
+|##|##|,|,|##|##|##|&|\A |,|\A |,|\\|\A |&|
============================================================
============================================================
TEST 7: Random seq item
============================================================
||||||||||||||||
-| ,| ,| ,|| ,| ,| ,||| ,| ,||| ,||
-|,|\A |##|&|\A |,|\A |\A |,|##|\A |\A |##|&|##|
+| ,|| ,| ,| ,||||| ,|| ,| ,|||
+|\A |,|##|{\\}|\A |\A |\A |##|{\\}|,|##|\A |&|,|&|
============================================================
============================================================
TEST 8: Random prop key/value
============================================================
||||||||||||||||
-|{\a }{\A }|{\b }{{\B }}|{\a }{\A }|{\e }{}|{\a }{\A }|{\a }{\A }|{\b }{{\B }}|{\e }{}|{\a }{\A }|{\a }{\A }|{\a }{\A }|{\e }{}|{\b }{{\B }}|{\a }{\A }|{\a }{\A }|
+|{\b }{{\B }}|{\a }{\A }|{\b }{{\B }}|{\b }{{\B }}|{\a }{\A }|{\a }{\A }|{\e }{}|{\a }{\A }|{\e }{}|{\e }{}|{\a }{\A }|{\e }{}|{\b }{{\B }}|{\e }{}|{\b }{{\B }}|
============================================================
============================================================
TEST 9: sys rand commands
============================================================
1,71
0,25
-0,73
+0,36
1,71
-1,10
+1,55
============================================================
More information about the latex3-commits
mailing list