1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
## Copyright (C) 2000-2013 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)
|