# HG changeset patch # User David Bateman # Date 1206388387 14400 # Node ID 0483fad1d8880f7841219eba67049b7e2370b4e0 # Parent ec78d83a7fdea65c4572c4f2c82d6be37fcb67c8 Add the idivide function diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,7 @@ +2008-03-24 David Bateman + + * general/idivide.m: New function. + 2008-03-21 David Bateman * specfun/reallog.m, specfun/realpow.m, specfun/realsqrt.m: New diff --git a/scripts/general/Makefile.in b/scripts/general/Makefile.in --- a/scripts/general/Makefile.in +++ b/scripts/general/Makefile.in @@ -36,9 +36,9 @@ SOURCES = __isequal__.m __splinen__.m accumarray.m arrayfun.m bicubic.m \ bitcmp.m bitget.m bitset.m blkdiag.m cart2pol.m cart2sph.m cell2mat.m \ celldisp.m circshift.m common_size.m cplxpair.m cumtrapz.m deal.m del2.m \ - diff.m flipdim.m fliplr.m flipud.m gradient.m ind2sub.m int2str.m interp1.m \ - interp2.m interp3.m interpn.m interpft.m is_duplicate_entry.m isa.m \ - isdefinite.m isdir.m isequal.m isequalwithequalnans.m \ + diff.m flipdim.m fliplr.m flipud.m gradient.m idivide.m ind2sub.m int2str.m \ + interp1.m interp2.m interp3.m interpn.m interpft.m is_duplicate_entry.m \ + isa.m isdefinite.m isdir.m isequal.m isequalwithequalnans.m \ isscalar.m issquare.m issymmetric.m isvector.m logical.m logspace.m \ lookup.m mod.m nargchk.m nextpow2.m nthroot.m num2str.m perror.m \ pol2cart.m polyarea.m postpad.m prepad.m quadl.m randperm.m rat.m rem.m \ diff --git a/scripts/general/idivide.m b/scripts/general/idivide.m new file mode 100644 --- /dev/null +++ b/scripts/general/idivide.m @@ -0,0 +1,118 @@ +## Copyright (C) 2008 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} idivide (@var{x}, @var{y}, @var{op}) +## Integer division with different round rules. The standard behavior of +## the an 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 +## downwards. +## @item "ceil" +## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded +## upwards. +## @end table +## +## @noindent +## If @var{op} is not given it is assumed that it is @code{"fix"}. +## An example demonstrating these rounding rules is +## +## @example +## 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), "ceil") +## @result{} int8 ([0, 1]) +## idivide (int8 ([-3, 3]), int8 (4), "floor") +## @result{} int8 ([-1, 0]) +## @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)))