X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fm%2Fstrings%2Fdec2base.m;fp=octave_packages%2Fm%2Fstrings%2Fdec2base.m;h=72fc6bc2ef1611e2e8ab9e1043d5713e38c1135f;hp=0000000000000000000000000000000000000000;hb=1c0469ada9531828709108a4882a751d2816994a;hpb=63de9f36673d49121015e3695f2c336ea92bc278 diff --git a/octave_packages/m/strings/dec2base.m b/octave_packages/m/strings/dec2base.m new file mode 100644 index 0000000..72fc6bc --- /dev/null +++ b/octave_packages/m/strings/dec2base.m @@ -0,0 +1,167 @@ +## Copyright (C) 2000-2012 Daniel Calvelo +## +## 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} {} dec2base (@var{d}, @var{base}) +## @deftypefnx {Function File} {} dec2base (@var{d}, @var{base}, @var{len}) +## Return a string of symbols in base @var{base} corresponding to +## the non-negative integer @var{d}. +## +## @example +## @group +## dec2base (123, 3) +## @result{} "11120" +## @end group +## @end example +## +## If @var{d} is a matrix or cell array, return a string matrix with one +## row per element in @var{d}, padded with leading zeros to the width of +## the largest value. +## +## If @var{base} is a string then the characters of @var{base} are used as +## the symbols for the digits of @var{d}. Space (' ') may not be used +## as a symbol. +## +## @example +## @group +## dec2base (123, "aei") +## @result{} "eeeia" +## @end group +## @end example +## +## The optional third argument, @var{len}, specifies the minimum +## number of digits in the result. +## @seealso{base2dec, dec2bin, dec2hex} +## @end deftypefn + +## Author: Daniel Calvelo +## Adapted-by: Paul Kienzle + +function retval = dec2base (d, base, len) + + if (nargin < 2 || nargin > 3) + print_usage (); + endif + + if (iscell (d)) + d = cell2mat (d); + endif + + # Create column vector for algorithm + if (! iscolumn (d)) + d = d(:); + endif + + if (! isnumeric (d) || iscomplex (d) || any (d < 0 | d != fix (d))) + error ("dec2base: input must be real non-negative integers"); + endif + + symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (ischar (base)) + symbols = base; + base = length (symbols); + if (length (unique (symbols)) != base) + error ("dec2base: symbols representing digits must be unique"); + endif + if (any (isspace (symbols))) + error ("dec2base: whitespace characters are not valid symbols"); + endif + elseif (! isscalar (base)) + error ("dec2base: cannot convert from several bases at once"); + elseif (base < 2 || base > length (symbols)) + error ("dec2base: BASE must be between 2 and 36, or a string of symbols"); + endif + + ## determine number of digits required to handle all numbers, can overflow + ## by 1 digit + max_len = round (log (max (max (d(:)), 1)) / log (base)) + 1; + + if (nargin == 3) + max_len = max (max_len, len); + endif + + ## determine digits for each number + digits = zeros (length (d), max_len); + for k = max_len:-1:1 + digits(:,k) = mod (d, base); + d = round ((d - digits(:,k)) / base); + endfor + + ## convert digits to symbols + retval = reshape (symbols(digits+1), size (digits)); + + ## Check if the first element is the zero symbol. It seems possible + ## that LEN is provided, and is less than the computed MAX_LEN and + ## MAX_LEN is computed to be one larger than necessary, so we would + ## have a leading zero to remove. But if LEN >= MAX_LEN, we should + ## not remove any leading zeros. + if ((nargin == 2 || (nargin == 3 && max_len > len)) + && length (retval) != 1 && ! any (retval(:,1) != symbols(1))) + retval = retval(:,2:end); + endif + +endfunction + + +%!test +%! s0 = ''; +%! for n = 1:13 +%! for b = 2:16 +%! pp = dec2base (b^n+1, b); +%! assert (dec2base(b^n, b), ['1',s0,'0']); +%! assert (dec2base(b^n+1, b), ['1',s0,'1']); +%! endfor +%! s0 = [s0,'0']; +%! endfor + +%!test +%! digits='0123456789ABCDEF'; +%! for n = 1:13 +%! for b = 2:16 +%! pm = dec2base(b^n-1, b); +%! assert (length (pm), n); +%! assert (all (pm==digits(b))); +%! endfor +%! endfor + +%!test +%! for b = 2:16 +%! assert (dec2base (0, b), '0'); +%! endfor + +%!assert(dec2base (0, 2, 4), "0000"); +%!assert(dec2base (2^51-1, 2), ... +%! '111111111111111111111111111111111111111111111111111'); +%!assert(dec2base(uint64(2)^63-1, 16), '7FFFFFFFFFFFFFFF'); +%!assert(dec2base([1, 2; 3, 4], 2, 3), ["001"; "011"; "010"; "100"]); +%!assert(dec2base({1, 2; 3, 4}, 2, 3), ["001"; "011"; "010"; "100"]); + +%%Test input validation +%!error dec2base () +%!error dec2base (1) +%!error dec2base (1, 2, 3, 4) +%!error dec2base ("A") +%!error dec2base (2i) +%!error dec2base (-1) +%!error dec2base (1.1) +%!error dec2base (1, "ABA") +%!error dec2base (1, "A B") +%!error dec2base (1, ones(2)) +%!error dec2base (1, 1) +%!error dec2base (1, 37) +