]> Creatis software - CreaPhase.git/blobdiff - octave_packages/m/general/idivide.m
update packages
[CreaPhase.git] / octave_packages / m / general / idivide.m
diff --git a/octave_packages/m/general/idivide.m b/octave_packages/m/general/idivide.m
new file mode 100644 (file)
index 0000000..2428a30
--- /dev/null
@@ -0,0 +1,124 @@
+## Copyright (C) 2008-2012 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} idivide (@var{x}, @var{y}, @var{op})
+## Integer division with different rounding rules.
+##
+## The standard behavior of integer division such as @code{@var{a} ./ @var{b}}
+## is to round the result to the nearest integer.  This is not always the
+## desired behavior and @code{idivide} permits integer element-by-element
+## division to be performed with different treatment for the fractional
+## part of the division as determined by the @var{op} flag.  @var{op} is
+## a string with one of the values:
+##
+## @table @asis
+## @item "fix"
+## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+## towards zero.
+##
+## @item "round"
+## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+## towards the nearest integer.
+##
+## @item "floor"
+## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+## towards negative infinity.
+##
+## @item "ceil"
+## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
+## towards positive infinity.
+## @end table
+##
+## @noindent
+## If @var{op} is not given it defaults to @code{"fix"}.
+## An example demonstrating these rounding rules is
+##
+## @example
+## @group
+## idivide (int8 ([-3, 3]), int8 (4), "fix")
+##   @result{} int8 ([0, 0])
+## idivide (int8 ([-3, 3]), int8 (4), "round")
+##   @result{} int8 ([-1, 1])
+## idivide (int8 ([-3, 3]), int8 (4), "floor")
+##   @result{} int8 ([-1, 0])
+## idivide (int8 ([-3, 3]), int8 (4), "ceil")
+##   @result{} int8 ([0, 1])
+## @end group
+## @end example
+##
+## @seealso{ldivide, rdivide}
+## @end deftypefn
+
+function z = idivide (x, y, op)
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  elseif (nargin == 2)
+    op = "fix";
+  else
+    op = tolower (op);
+  endif
+
+  if (strcmp (op, "round"))
+    z = x ./ y;
+  else
+    if (isfloat (x))
+      typ = class (y);
+    elseif (isfloat (y))
+      typ = class (x);
+    else
+      typ = class (x);
+      if (!strcmp (class (x), class (y)))
+        error ("idivide: incompatible types");
+      endif
+    endif
+
+    if (strcmp (op, "fix"))
+      z = cast (fix (double (x) ./ double (y)), typ);
+    elseif (strcmp (op, "floor"))
+      z = cast (floor (double (x) ./ double (y)), typ);
+    elseif (strcmp (op, "ceil"))
+      z = cast (ceil (double (x) ./ double (y)), typ);
+    else
+      error ("idivide: unrecognized rounding type");
+    endif
+  endif
+endfunction
+
+%!shared a, af, b, bf
+%! a = int8(3);
+%! af = 3;
+%! b = int8([-4, 4]);
+%! bf = [-4, 4];
+
+%!assert (idivide (a, b), int8 ([0, 0]))
+%!assert (idivide (a, b, "floor"), int8([-1, 0]))
+%!assert (idivide (a, b, "ceil"), int8 ([0, 1]))
+%!assert (idivide (a, b, "round"), int8 ([-1, 1]))
+
+%!assert (idivide (af, b), int8 ([0, 0]))
+%!assert (idivide (af, b, "floor"), int8([-1, 0]))
+%!assert (idivide (af, b, "ceil"), int8 ([0, 1]))
+%!assert (idivide (af, b, "round"), int8 ([-1, 1]))
+
+%!assert (idivide (a, bf), int8 ([0, 0]))
+%!assert (idivide (a, bf, "floor"), int8([-1, 0]))
+%!assert (idivide (a, bf, "ceil"), int8 ([0, 1]))
+%!assert (idivide (a, bf, "round"), int8 ([-1, 1]))
+
+%!error (idivide (uint8(1), int8(1)))