]> Creatis software - CreaPhase.git/blobdiff - octave_packages/m/strings/base2dec.m
update packages
[CreaPhase.git] / octave_packages / m / strings / base2dec.m
diff --git a/octave_packages/m/strings/base2dec.m b/octave_packages/m/strings/base2dec.m
new file mode 100644 (file)
index 0000000..0bc5e3a
--- /dev/null
@@ -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
+## <http://www.gnu.org/licenses/>.
+
+## -*- 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 <dcalvelo@yahoo.com>
+## Adapted-by: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
+
+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);
+