1## Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008,
4## This file is part of Octave.
6## Octave is free software; you can redistribute it and/or modify it
7## under the terms of the GNU General Public License as published by
8## the Free Software Foundation; either version 3 of the License, or (at
9## your option) any later version.
11## Octave is distributed in the hope that it will be useful, but
12## WITHOUT ANY WARRANTY; without even the implied warranty of
13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14## General Public License for more details.
16## You should have received a copy of the GNU General Public License
17## along with Octave; see the file COPYING. If not, see
18## <http://www.gnu.org/licenses/>.
21## @deftypefn {Mapping Function} {} mod (@var{x}, @var{y})
22## Compute the modulo of @var{x} and @var{y}. Conceptually this is given by
25## x - y .* floor (x ./ y)
28## and is written such that the correct modulus is returned for
29## integer types. This function handles negative values correctly. That
30## is, @code{mod (-1, 3)} is 2, not -1, as @code{rem (-1, 3)} returns.
31## @code{mod (@var{x}, 0)} returns @var{x}.
33## An error results if the dimensions of the arguments do not agree, or if
34## either of the arguments is complex.
38## Author: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
39## Modified by: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
42function r = mod (x, y)
48 if (! size_equal (x, y) && ! (isscalar (x) || isscalar (y)))
49 error ("mod: argument sizes must agree");
52 if (isreal (x) && isreal (y))
55 ## No elements of y are zero.
56 if (isinteger(x) || isinteger(y))
62 r = x - y .* cast (floor (double(x) ./ double(y)), typ);
64 r = x - y .* floor (x ./ y);
70 ## Some elements of y are zero.
72 r = x * ones (size(y), class(y));
78 if (isinteger(x) || isinteger(y))
84 r(nz) = x - y .* floor (double(x) ./ double(y));
86 r(nz) = x - y .* floor (x ./ y);
90 error ("mod: complex arguments are not allowed");
96%!assert (isempty(mod([], [])));
98## x mod y, y != 0 tests
99%!assert (mod(5, 3), 2);
100%!assert (mod(-5, 3), 1);
101%!assert (mod(0, 3), 0);
102%!assert (mod([-5, 5, 0], [3, 3, 3]), [1, 2, 0]);
103%!assert (mod([-5; 5; 0], [3; 3; 3]), [1; 2; 0]);
104%!assert (mod([-5, 5; 0, 3], [3, 3 ; 3, 1]), [1, 2 ; 0, 0]);
107%!assert (mod(5, 0), 5);
108%!assert (mod(-5, 0), -5);
109%!assert (mod([-5, 5, 0], [3, 0, 3]), [1, 5, 0]);
110%!assert (mod([-5; 5; 0], [3; 0; 3]), [1; 5; 0]);
111%!assert (mod([-5, 5; 0, 3], [3, 0 ; 3, 1]), [1, 5 ; 0, 0]);
112%!assert (mod([-5, 5; 0, 3], [0, 0 ; 0, 0]), [-5, 5; 0, 3]);
114## mixed scalar/matrix tests
115%!assert (mod([-5, 5; 0, 3], 0), [-5, 5; 0, 3]);
116%!assert (mod([-5, 5; 0, 3], 3), [1, 2; 0, 0]);
117%!assert (mod(-5,[0,0; 0,0]), [-5, -5; -5, -5]);
118%!assert (mod(-5,[3,0; 3,1]), [1, -5; 1, 0]);
119%!assert (mod(-5,[3,2; 3,1]), [1, 1; 1, 0]);
122%!assert (mod(uint8(5),uint8(4)),uint8(1))
123%!assert (mod(uint8([1:5]),uint8(4)),uint8([1,2,3,0,1]))
124%!assert (mod(uint8([1:5]),uint8(0)),uint8([1:5]))
125%!error (mod(uint8(5),int8(4)))
127## mixed integer/real types
128%!assert (mod(uint8(5),4),uint8(1))
129%!assert (mod(5,uint8(4)),uint8(1))
130%!assert (mod(uint8([1:5]),4),uint8([1,2,3,0,1]))