summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3kernel/l3fp-random.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3fp-random.dtx')
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-random.dtx527
1 files changed, 245 insertions, 282 deletions
diff --git a/macros/latex/contrib/l3kernel/l3fp-random.dtx b/macros/latex/contrib/l3kernel/l3fp-random.dtx
index ba0a9a8e23..94313834ba 100644
--- a/macros/latex/contrib/l3kernel/l3fp-random.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-random.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-04-20}
+% \date{Released 2023-05-05}
%
% \maketitle
%
@@ -73,37 +73,6 @@
%
% \subsection{Engine support}
%
-% Most engines provide random numbers, but not all. We write the test
-% twice simply in order to write the \texttt{false} branch first.
-% \begin{macrocode}
-\sys_if_rand_exist:F
- {
- \msg_new:nnn { kernel } { fp-no-random }
- { Random~numbers~unavailable~for~#1 }
- \cs_new:Npn \@@_rand_o:Nw ? #1 @
- {
- \msg_expandable_error:nnn { kernel } { fp-no-random }
- { fp~rand }
- \exp_after:wN \c_nan_fp
- }
- \cs_new_eq:NN \@@_randint_o:Nw \@@_rand_o:Nw
- \cs_new:Npn \int_rand:nn #1#2
- {
- \msg_expandable_error:nnn { kernel } { fp-no-random }
- { \int_rand:nn {#1} {#2} }
- \int_eval:n {#1}
- }
- \cs_new:Npn \int_rand:n #1
- {
- \msg_expandable_error:nnn { kernel } { fp-no-random }
- { \int_rand:n {#1} }
- 1
- }
- }
-\sys_if_rand_exist:T
- {
-% \end{macrocode}
-%
% Obviously, every word \enquote{random} below means
% \enquote{pseudo-random}, as we have no access to entropy (except a
% very unreliable source of entropy: the time it takes to run some
@@ -271,7 +240,7 @@
% Constant equal to $2^{17}-1$, the maximal size of a range that
% \cs{int_range:nn} can do with its \enquote{simple} algorithm.
% \begin{macrocode}
- \int_const:Nn \c__kernel_randint_max_int { 131071 }
+\int_const:Nn \c__kernel_randint_max_int { 131071 }
% \end{macrocode}
% \end{variable}
%
@@ -284,11 +253,11 @@
% $\operatorname{ediv}(p-2^{13},2^{14})$ but that wrongly gives $-1$
% for $p=0$.
% \begin{macrocode}
- \cs_new:Npn \__kernel_randint:n #1
- {
- (#1 * \tex_uniformdeviate:D 16384
- + \tex_uniformdeviate:D #1 + 8192 ) / 16384
- }
+\cs_new:Npn \__kernel_randint:n #1
+ {
+ (#1 * \tex_uniformdeviate:D 16384
+ + \tex_uniformdeviate:D #1 + 8192 ) / 16384
+ }
% \end{macrocode}
% \end{macro}
%
@@ -300,17 +269,17 @@
% 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
- {
- #1
- \exp_after:wN \@@_rand_myriads_get:w
- \int_value:w \@@_int_eval:w 9999 +
- \__kernel_randint:n { 10000 }
- \@@_rand_myriads_loop:w
- }
- \cs_new:Npn \@@_rand_myriads_get:w 1 #1 ; { ; {#1} }
+\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
+ {
+ #1
+ \exp_after:wN \@@_rand_myriads_get:w
+ \int_value:w \@@_int_eval:w 9999 +
+ \__kernel_randint:n { 10000 }
+ \@@_rand_myriads_loop:w
+ }
+\cs_new:Npn \@@_rand_myriads_get:w 1 #1 ; { ; {#1} }
% \end{macrocode}
% \end{macro}
%
@@ -324,27 +293,27 @@
% is correctly~$0$ but it raises the \texttt{underflow} flag; it
% should not do that.
% \begin{macrocode}
- \cs_new:Npn \@@_rand_o:Nw ? #1 @
+\cs_new:Npn \@@_rand_o:Nw ? #1 @
+ {
+ \tl_if_empty:nTF {#1}
{
- \tl_if_empty:nTF {#1}
- {
- \exp_after:wN \@@_rand_o:w
- \exp:w \exp_end_continue_f:w
- \@@_rand_myriads:n { XXXX } { 0000 } { 0000 } ; 0
- }
- {
- \msg_expandable_error:nnnnn
- { fp } { num-args } { rand() } { 0 } { 0 }
- \exp_after:wN \c_nan_fp
- }
+ \exp_after:wN \@@_rand_o:w
+ \exp:w \exp_end_continue_f:w
+ \@@_rand_myriads:n { XXXX } { 0000 } { 0000 } ; 0
}
- \cs_new:Npn \@@_rand_o:w ;
{
- \exp_after:wN \@@_sanitize:Nw
- \exp_after:wN 0
- \int_value:w \@@_int_eval:w \c_zero_int
- \@@_fixed_to_float_o:wN
+ \msg_expandable_error:nnnnn
+ { fp } { num-args } { rand() } { 0 } { 0 }
+ \exp_after:wN \c_nan_fp
}
+ }
+\cs_new:Npn \@@_rand_o:w ;
+ {
+ \exp_after:wN \@@_sanitize:Nw
+ \exp_after:wN 0
+ \int_value:w \@@_int_eval:w \c_zero_int
+ \@@_fixed_to_float_o:wN
+ }
% \end{macrocode}
% \end{macro}
%
@@ -382,115 +351,115 @@
% 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 ?
- {
- \@@_parse_function_one_two:nnw
- { randint }
- { \@@_randint_default:w \@@_randint_o:w }
- }
- \cs_new:Npn \@@_randint_default:w #1 { \exp_after:wN #1 \c_one_fp }
- \cs_new:Npn \@@_randint_badarg:w \s_@@ \@@_chk:w #1#2#3;
- {
- \@@_int:wTF \s_@@ \@@_chk:w #1#2#3;
- {
- \if_meaning:w 1 #1
- \if_int_compare:w
- \@@_use_i_until_s:nw #3 ; > \c_@@_prec_int
- \c_one_int
- \fi:
- \fi:
- }
- { \c_one_int }
- }
- \cs_new:Npn \@@_randint_o:w #1; #2; @
- {
- \if_case:w
- \@@_randint_badarg:w #1;
- \@@_randint_badarg:w #2;
- \if:w 1 \@@_compare_back:ww #2; #1; \c_one_int \fi:
- \c_zero_int
- \@@_randint_auxi_o:ww #1; #2;
- \or:
- \@@_invalid_operation_tl_o:ff
- { randint } { \@@_array_to_clist:n { #1; #2; } }
- \exp:w
- \fi:
- \exp_after:wN \exp_end:
- }
- \cs_new:Npn \@@_randint_auxi_o:ww #1 ; #2 ; #3 \exp_end:
- {
- \fi:
- \@@_randint_auxii:wn #2 ;
- { \@@_randint_auxii:wn #1 ; \@@_randint_auxiii_o:ww }
- }
- \cs_new:Npn \@@_randint_auxii:wn \s_@@ \@@_chk:w #1#2#3#4 ;
- {
- \if_meaning:w 0 #1
- \exp_after:wN \use_i:nn
- \else:
- \exp_after:wN \use_ii:nn
- \fi:
- { \exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl }
- {
- \exp_after:wN \@@_ep_to_fixed:wwn
- \int_value:w \@@_int_eval:w
- #3 - \c_@@_prec_int , #4 {0000} {0000} ;
- {
- \if_meaning:w 0 #2
- \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_auxiii_o:ww #1 ; #2 ;
- {
- \@@_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_auxiv_o:ww #1#2#3#4#5 ; #6#7#8#9
+\cs_new:Npn \@@_randint_o:Nw ?
+ {
+ \@@_parse_function_one_two:nnw
+ { randint }
+ { \@@_randint_default:w \@@_randint_o:w }
+ }
+\cs_new:Npn \@@_randint_default:w #1 { \exp_after:wN #1 \c_one_fp }
+\cs_new:Npn \@@_randint_badarg:w \s_@@ \@@_chk:w #1#2#3;
+ {
+ \@@_int:wTF \s_@@ \@@_chk:w #1#2#3;
{
- \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
+ \if_meaning:w 1 #1
+ \if_int_compare:w
+ \@@_use_i_until_s:nw #3 ; > \c_@@_prec_int
+ \c_one_int
+ \fi:
\fi:
- \@@_randint_auxv_o:w {#1}{#2}{#3}{#4}#5
}
- \cs_new:Npn \@@_randint_auxv_o:w #1#2#3#4#5 ; #6 @
+ { \c_one_int }
+ }
+\cs_new:Npn \@@_randint_o:w #1; #2; @
+ {
+ \if_case:w
+ \@@_randint_badarg:w #1;
+ \@@_randint_badarg:w #2;
+ \if:w 1 \@@_compare_back:ww #2; #1; \c_one_int \fi:
+ \c_zero_int
+ \@@_randint_auxi_o:ww #1; #2;
+ \or:
+ \@@_invalid_operation_tl_o:ff
+ { randint } { \@@_array_to_clist:n { #1; #2; } }
+ \exp:w
+ \fi:
+ \exp_after:wN \exp_end:
+ }
+\cs_new:Npn \@@_randint_auxi_o:ww #1 ; #2 ; #3 \exp_end:
+ {
+ \fi:
+ \@@_randint_auxii:wn #2 ;
+ { \@@_randint_auxii:wn #1 ; \@@_randint_auxiii_o:ww }
+ }
+\cs_new:Npn \@@_randint_auxii:wn \s_@@ \@@_chk:w #1#2#3#4 ;
+ {
+ \if_meaning:w 0 #1
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ { \exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl }
+ {
+ \exp_after:wN \@@_ep_to_fixed:wwn
+ \int_value:w \@@_int_eval:w
+ #3 - \c_@@_prec_int , #4 {0000} {0000} ;
{
- \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
+ \if_meaning:w 0 #2
+ \exp_after:wN \use_i:nnnn
+ \exp_after:wN \@@_fixed_add_one:wN
\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:
}
+ \@@_fixed_continue:wn
+ }
+ }
+\cs_new:Npn \@@_randint_auxiii_o:ww #1 ; #2 ;
+ {
+ \@@_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_auxiv_o:ww #1#2#3#4#5 ; #6#7#8#9
+ {
+ \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_auxv_o:w #1#2#3#4#5 ; #6 @
+ {
+ \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}
@@ -504,38 +473,38 @@
% where \meta{choices} is the number of possible outcomes. If the
% range is wide, use somewhat slower code.
% \begin{macrocode}
- \cs_new:Npn \int_rand:nn #1#2
+\cs_new:Npn \int_rand:nn #1#2
+ {
+ \int_eval:n
{
- \int_eval:n
- {
- \exp_after:wN \@@_randint:ww
- \int_value:w \int_eval:n {#1} \exp_after:wN ;
- \int_value:w \int_eval:n {#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;
- {
- \if_int_compare:w #1 > #2 \exp_stop_f:
- \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_int
- - #1 < \@@_int_eval:w
- \else:
- < \@@_int_eval:w #1 +
- \fi:
- \c__kernel_randint_max_int
- \@@_int_eval_end:
- \__kernel_randint:n
- { \@@_int_eval:w #2 - #1 + 1 \@@_int_eval_end: }
- - 1 + #1
+ }
+\cs_new:Npn \@@_randint:ww #1; #2;
+ {
+ \if_int_compare:w #1 > #2 \exp_stop_f:
+ \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_int
+ - #1 < \@@_int_eval:w
\else:
- \__kernel_randint:nn {#1} {#2}
+ < \@@_int_eval:w #1 +
\fi:
- \fi:
- }
+ \c__kernel_randint_max_int
+ \@@_int_eval_end:
+ \__kernel_randint:n
+ { \@@_int_eval:w #2 - #1 + 1 \@@_int_eval_end: }
+ - 1 + #1
+ \else:
+ \__kernel_randint:nn {#1} {#2}
+ \fi:
+ \fi:
+ }
% \end{macrocode}
% \end{macro}
%
@@ -557,101 +526,95 @@
% \meta{Y_1}|;|\meta{Y_0}|;| \meta{R_2}|;|\meta{R_1}|;|\meta{R_0}|;.|
% and we apply the algorithm described earlier.
% \begin{macrocode}
- \cs_new:Npn \__kernel_randint:nn #1#2
- {
- #1
- \exp_after:wN \@@_randint_wide_aux:w
- \int_value:w
- \exp_after:wN \@@_randint_split_o:Nw
- \tex_uniformdeviate:D 268435456 ;
- \int_value:w
- \exp_after:wN \@@_randint_split_o:Nw
- \tex_uniformdeviate:D 268435456 ;
+\cs_new:Npn \__kernel_randint:nn #1#2
+ {
+ #1
+ \exp_after:wN \@@_randint_wide_aux:w
+ \int_value:w
+ \exp_after:wN \@@_randint_split_o:Nw
+ \tex_uniformdeviate:D 268435456 ;
+ \int_value:w
+ \exp_after:wN \@@_randint_split_o:Nw
+ \tex_uniformdeviate:D 268435456 ;
+ \int_value:w
+ \exp_after:wN \@@_randint_split_o:Nw
+ \int_value:w \@@_int_eval:w 131072 +
+ \exp_after:wN \@@_randint_split_o:Nw
\int_value:w
- \exp_after:wN \@@_randint_split_o:Nw
- \int_value:w \@@_int_eval:w 131072 +
- \exp_after:wN \@@_randint_split_o:Nw
- \int_value:w
- \__kernel_int_add:nnn {#2} { -#1 } { -\c_max_int } ;
- .
- }
- \cs_new:Npn \@@_randint_split_o:Nw #1#2 ;
- {
- \if_meaning:w 0 #1
- 0 \exp_after:wN ; \int_value:w 0
- \else:
- \exp_after:wN \@@_randint_split_aux:w
- \int_value:w \@@_int_eval:w (#1#2 - 8192) / 16384 ;
- + #1#2
- \fi:
- \exp_after:wN ;
- }
- \cs_new:Npn \@@_randint_split_aux:w #1 ;
- {
- #1 \exp_after:wN ;
- \int_value:w \@@_int_eval:w - #1 * 16384
- }
- \cs_new:Npn \@@_randint_wide_aux:w #1;#2; #3;#4; #5;#6;#7; .
- {
- \exp_after:wN \@@_randint_wide_auxii:w
- \int_value:w \@@_int_eval:w #5 * #3 + #6 * #1 +
- (#5 * #4 + #6 * #3 + #7 * #1 +
- (#5 * #2 + #7 * #3 +
- (16384 * #6 + #7) * (16384 * #4 + #2) / 268435456) / 16384
- ) / 16384 \exp_after:wN ;
- \int_value:w \@@_int_eval:w (#5 + #6) * 16384 + #7 ;
- #1 ; #5 ;
- }
- \cs_new:Npn \@@_randint_wide_auxii:w #1; #2; #3; #4;
- {
- \if_int_odd:w 0
- \if_int_compare:w #1 = #2 \else: \exp_stop_f: \fi:
- \if_int_compare:w #4 = \c_zero_int 1 \fi:
- \if_int_compare:w #3 = 16383 ~ 1 \fi:
- \exp_stop_f:
- \exp_after:wN \prg_break:
- \fi:
- \if_int_compare:w #4 < 8 \exp_stop_f:
- + #4 * #3 * 16384
- \else:
- + 8 * #3 * 16384 + (#4 - 8) * #3 * 16384
- \fi:
- + #1
- \prg_break_point:
- }
+ \__kernel_int_add:nnn {#2} { -#1 } { -\c_max_int } ;
+ .
+ }
+\cs_new:Npn \@@_randint_split_o:Nw #1#2 ;
+ {
+ \if_meaning:w 0 #1
+ 0 \exp_after:wN ; \int_value:w 0
+ \else:
+ \exp_after:wN \@@_randint_split_aux:w
+ \int_value:w \@@_int_eval:w (#1#2 - 8192) / 16384 ;
+ + #1#2
+ \fi:
+ \exp_after:wN ;
+ }
+\cs_new:Npn \@@_randint_split_aux:w #1 ;
+ {
+ #1 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w - #1 * 16384
+ }
+\cs_new:Npn \@@_randint_wide_aux:w #1;#2; #3;#4; #5;#6;#7; .
+ {
+ \exp_after:wN \@@_randint_wide_auxii:w
+ \int_value:w \@@_int_eval:w #5 * #3 + #6 * #1 +
+ (#5 * #4 + #6 * #3 + #7 * #1 +
+ (#5 * #2 + #7 * #3 +
+ (16384 * #6 + #7) * (16384 * #4 + #2) / 268435456) / 16384
+ ) / 16384 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w (#5 + #6) * 16384 + #7 ;
+ #1 ; #5 ;
+ }
+\cs_new:Npn \@@_randint_wide_auxii:w #1; #2; #3; #4;
+ {
+ \if_int_odd:w 0
+ \if_int_compare:w #1 = #2 \else: \exp_stop_f: \fi:
+ \if_int_compare:w #4 = \c_zero_int 1 \fi:
+ \if_int_compare:w #3 = 16383 ~ 1 \fi:
+ \exp_stop_f:
+ \exp_after:wN \prg_break:
+ \fi:
+ \if_int_compare:w #4 < 8 \exp_stop_f:
+ + #4 * #3 * 16384
+ \else:
+ + 8 * #3 * 16384 + (#4 - 8) * #3 * 16384
+ \fi:
+ + #1
+ \prg_break_point:
+ }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\int_rand:n, \@@_randint:n}
% Similar to \cs{int_rand:nn}, but needs fewer checks.
% \begin{macrocode}
- \cs_new:Npn \int_rand:n #1
- {
- \int_eval:n
- { \exp_args:Nf \@@_randint:n { \int_eval:n {#1} } }
- }
- \cs_new:Npn \@@_randint:n #1
- {
- \if_int_compare:w #1 < \c_one_int
- \msg_expandable_error:nnnn
- { kernel } { randint-backward-range } { 1 } {#1}
- \@@_randint:ww #1; 1;
- \else:
- \if_int_compare:w #1 > \c__kernel_randint_max_int
- \__kernel_randint:nn { 1 } {#1}
- \else:
- \__kernel_randint:n {#1}
- \fi:
- \fi:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% End the initial conditional that ensures these commands are only
-% defined in engines that support random numbers.
-% \begin{macrocode}
+\cs_new:Npn \int_rand:n #1
+ {
+ \int_eval:n
+ { \exp_args:Nf \@@_randint:n { \int_eval:n {#1} } }
+ }
+\cs_new:Npn \@@_randint:n #1
+ {
+ \if_int_compare:w #1 < \c_one_int
+ \msg_expandable_error:nnnn
+ { kernel } { randint-backward-range } { 1 } {#1}
+ \@@_randint:ww #1; 1;
+ \else:
+ \if_int_compare:w #1 > \c__kernel_randint_max_int
+ \__kernel_randint:nn { 1 } {#1}
+ \else:
+ \__kernel_randint:n {#1}
+ \fi:
+ \fi:
}
% \end{macrocode}
+% \end{macro}
%
% \begin{macrocode}
%</package>