changeset 20767:e0e55ce86ba0 stable

randi.m: Clean up function. * randi.m: Document the typical IMAX value in docstring. Don't check number of outputs with nargoutchk. Issue error if either IMIN or IMAX exceeds flintmax. Report the invalid output class when issuing error. Tighten input validation by looking for specific error messages.
author Rik <rik@octave.org>
date Fri, 27 Nov 2015 02:30:06 -0800
parents a34e5739538c
children 51ab9145f6e6
files scripts/general/randi.m
diffstat 1 files changed, 31 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/general/randi.m	Fri Nov 27 09:46:40 2015 +0100
+++ b/scripts/general/randi.m	Fri Nov 27 02:30:06 2015 -0800
@@ -46,7 +46,8 @@
 ## Implementation Note: @code{randi} relies internally on @code{rand} which
 ## uses class @qcode{"double"} to represent numbers.  This limits the maximum
 ## integer (@var{imax}) and range (@var{imax} - @var{imin}) to the value
-## returned by the @code{flintmax} function.
+## returned by the @code{flintmax} function.  For IEEE floating point numbers
+## this value is @w{@math{2^{53} - 1}}.
 ##
 ## @seealso{rand}
 ## @end deftypefn
@@ -58,7 +59,6 @@
   if (nargin < 1)
     print_usage ();
   endif
-  nargoutchk (0, 1);
 
   if (! (isnumeric (bounds) && all (bounds == fix (bounds))))
     error ("randi: IMIN and IMAX must be integer bounds");
@@ -88,7 +88,7 @@
 
   ## Limit set by use of class double in rand(): Any consecutive integer in the
   ## range [-flintmax(), flintmax()] can be represented by a double.
-  if ((abs (imax) >= flintmax ()) && (abs (imin) >= flintmax ()))
+  if ((abs (imax) >= flintmax ()) || (abs (imin) >= flintmax ()))
     error ("randi: IMIN and IMAX must be smaller than flintmax()");
   endif
   if ((imax - imin) >= (flintmax () - 1))
@@ -105,14 +105,14 @@
       maxval = double (flintmax (rclass));
       minval = -maxval;
     else
-      error ("randi: unknown requested output class");
+      error ("randi: unknown requested output class '%s'", rclass);
     endif
     if (imax > maxval)
-      warning (["randi: integer IMAX exceeds requested type.  Values ", ...
-        "might be truncated to requested type."]);
+      warning (["randi: integer IMAX exceeds requested type.  ", ...
+                "Values might be truncated to requested type."]);
     elseif (imin < minval)
-      warning (["randi: integer IMIN exceeds requested type.  Values ", ...
-        "might be truncated to requested type."]);
+      warning (["randi: integer IMIN exceeds requested type.  ", ...
+                " Values might be truncated to requested type."]);
     endif
 
     ri = cast (ri, rclass);
@@ -129,6 +129,8 @@
 %! assert (rows (ri), 1000);
 %! assert (columns (ri), 1);
 %! assert (class (ri), "double");
+## FIXME: Does Octave guarantee support for int64 even when underlying hardware
+##        is 32-bit?
 %!test
 %! ri = randi (int64 (100), 1, 1000);
 %! assert (ri, fix (ri));
@@ -149,17 +151,17 @@
 %! assert (min (ri), single (-5));
 %! assert (max (ri), single (10));
 %! assert (class (ri), "single");
-%!
+
 %!assert (size (randi (10, 3, 1, 2)), [3, 1, 2])
 
 %!shared max_int8, min_int8, max_uint8, min_uint8, max_single
-%!  max_int8 = double (intmax ("int8"));
-%!  min_int8 = double (intmin ("int8"));
-%!  max_uint8 = double (intmax ("uint8"));
-%!  min_uint8 = double (intmin ("uint8"));
-%!  max_single = double (flintmax ("single"));
+%! max_int8 = double (intmax ("int8"));
+%! min_int8 = double (intmin ("int8"));
+%! max_uint8 = double (intmax ("uint8"));
+%! min_uint8 = double (intmin ("uint8"));
+%! max_single = double (flintmax ("single"));
 
-## Test no warning being thrown if on the limits of the range
+## Test that no warning thrown if IMAX is exactly on the limits of the range
 %!function test_no_warning (func, varargin)
 %! state = warning ("query");
 %! unwind_protect
@@ -176,7 +178,7 @@
 %!test test_no_warning (@randi, [min_uint8, max_uint8], "uint8");
 %!test test_no_warning (@randi, [-max_single, max_single], "single");
 
-## Test range exceedings
+## Test exceeding range
 %!warning <exceeds requested type>
 %! randi ([min_int8-1, max_int8], "int8");
 %!warning <exceeds requested type>
@@ -196,15 +198,16 @@
 
 
 ## Test input validation
-%!error (randi ())
-%!error (randi ("test"))
-%!error (randi (struct ("a", 1)))
-%!error (randi (0))
-%!error (randi (1.5))
-%!error (randi ([1.5, 2.5]))
-%!error (randi ([1, 2.5]))
-%!error (randi ([1.5, 2]))
-%!error (randi ([10, 1]))
-%!error (randi (flintmax ()))
-%!error (randi ([-1, flintmax() - 1]))
-%!error ([r1, r2] = randi ())
+%!error randi ()
+%!error <must be integer bounds> randi ("test")
+%!error <must be integer bounds> randi (struct ("a", 1))
+%!error <must be integer bounds> randi (1.5)
+%!error <must be integer bounds> randi ([1.5, 2.5])
+%!error <must be integer bounds> randi ([1, 2.5])
+%!error <must be integer bounds> randi ([1.5, 2])
+%!error <require IMAX .= 1> randi (0)
+%!error <require IMIN <= IMAX> randi ([10, 1])
+%!error <IMIN and IMAX must be smaller than flintmax\(\)> randi (flintmax ())
+%!error <range must be smaller than flintmax\(\)-1> randi ([-1, flintmax() - 1])
+%!error <unknown requested output class 'foo'> randi (10, "foo")
+