From 507fa9c669d7e4bc2c808f269113c6ced0b18827 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Sat, 6 May 2023 03:01:13 +0000
Subject: CTAN sync 202305060301

---
 macros/latex/contrib/l3kernel/l3fp-random.dtx | 527 ++++++++++++--------------
 1 file changed, 245 insertions(+), 282 deletions(-)

(limited to 'macros/latex/contrib/l3kernel/l3fp-random.dtx')

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>
-- 
cgit v1.2.3

