X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fm%2Fstrings%2Fbase2dec.m;fp=octave_packages%2Fm%2Fstrings%2Fbase2dec.m;h=0bc5e3a279ce7ccd7e2a4fc8d2d5c2fc1d4f0901;hp=0000000000000000000000000000000000000000;hb=1c0469ada9531828709108a4882a751d2816994a;hpb=63de9f36673d49121015e3695f2c336ea92bc278 diff --git a/octave_packages/m/strings/base2dec.m b/octave_packages/m/strings/base2dec.m new file mode 100644 index 0000000..0bc5e3a --- /dev/null +++ b/octave_packages/m/strings/base2dec.m @@ -0,0 +1,136 @@ +## 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} {} base2dec (@var{s}, @var{base}) +## Convert @var{s} from a string of digits in base @var{base} to a decimal +## integer (base 10). +## +## @example +## @group +## base2dec ("11120", 3) +## @result{} 123 +## @end group +## @end example +## +## If @var{s} is a string matrix, return a column vector with one value per +## row of @var{s}. If a row contains invalid symbols then the +## corresponding value will be NaN@. +## +## If @var{s} is a cell array of strings, return a column vector with one +## value per cell element in @var{s}. +## +## If @var{base} is a string, the characters of @var{base} are used as the +## symbols for the digits of @var{s}. Space (' ') may not be used as a +## symbol. +## +## @example +## @group +## base2dec ("yyyzx", "xyz") +## @result{} 123 +## @end group +## @end example +## @seealso{dec2base, bin2dec, hex2dec} +## @end deftypefn + +## Author: Daniel Calvelo +## Adapted-by: Paul Kienzle + +function out = base2dec (s, base) + + if (nargin != 2) + print_usage (); + endif + + if (iscellstr (s)) + s = char (s); + elseif (! ischar (s)) + error ("base2dec: S must be a string or cellstring"); + endif + + symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (ischar (base)) + symbols = base; + base = length (symbols); + if (length (unique (symbols)) != base) + error ("base2dec: symbols representing digits must be unique"); + endif + if (any (isspace (symbols))) + error ("base2dec: whitespace characters are not valid symbols"); + endif + elseif (! isscalar (base)) + error ("base2dec: cannot convert from several bases at once"); + elseif (base < 2 || base > length (symbols)) + error ("base2dec: BASE must be between 2 and 36, or a string of symbols"); + else + s = toupper (s); + endif + + ## Right justify the values and squeeze out any spaces. + ## This looks complicated, but indexing solution is very fast + ## compared to alternatives which use cellstr or cellfun or looping. + [nr, nc] = size (s); + if (nc > 1) # Bug #35621 + s = s.'; + nonbl = s != " "; + num_nonbl = sum (nonbl); + nc = max (num_nonbl); + num_blank = nc - num_nonbl; + R = repmat ([1 2; 0 0], 1, nr); + R(2, 1:2:2*nr) = num_blank; + R(2, 2:2:2*nr) = num_nonbl; + idx = repelems ([false, true], R); + idx = reshape (idx, nc, nr); + + ## Create a blank matrix and position the nonblank characters. + s2 = repmat (" ", nc, nr); + s2(idx) = s(nonbl); + s = s2.'; + endif + + ## Lookup value of symbols in symbol table, with invalid symbols + ## evaluating to NaN and space evaluating to 0. + table = NaN (1, 256); + table(toascii (symbols(1:base))) = 0 : base-1; + table(toascii (" ")) = 0; + s = reshape (table(toascii (s)), size (s)); + + ## Multiply the resulting digits by the appropriate power + ## and sum the rows. + out = s * (base .^ (columns(s)-1 : -1 : 0)'); + +endfunction + + +%!assert(base2dec ("11120", 3), 123); +%!assert(base2dec ("yyyzx", "xyz"), 123); +%!assert(base2dec ("-1", 2), NaN); +%!assert(base2dec ({"A1", "1A"}, 16), [161; 26]); + +%% Bug #35621 +%!assert (base2dec (["0"; "1"], 2), [0; 1]) + +%%Test input validation +%!error base2dec (); +%!error base2dec ("11120"); +%!error base2dec ("11120", 3, 4); +%!error base2dec ("11120", "1231"); +%!error base2dec ("11120", "12 3"); +%!error base2dec ("11120", ones(2)); +%!error base2dec ("11120", 37); +