1 ## Copyright (C) 2000-2012 Daniel Calvelo
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {} dec2base (@var{d}, @var{base})
21 ## @deftypefnx {Function File} {} dec2base (@var{d}, @var{base}, @var{len})
22 ## Return a string of symbols in base @var{base} corresponding to
23 ## the non-negative integer @var{d}.
32 ## If @var{d} is a matrix or cell array, return a string matrix with one
33 ## row per element in @var{d}, padded with leading zeros to the width of
36 ## If @var{base} is a string then the characters of @var{base} are used as
37 ## the symbols for the digits of @var{d}. Space (' ') may not be used
42 ## dec2base (123, "aei")
47 ## The optional third argument, @var{len}, specifies the minimum
48 ## number of digits in the result.
49 ## @seealso{base2dec, dec2bin, dec2hex}
52 ## Author: Daniel Calvelo <dcalvelo@yahoo.com>
53 ## Adapted-by: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
55 function retval = dec2base (d, base, len)
57 if (nargin < 2 || nargin > 3)
65 # Create column vector for algorithm
70 if (! isnumeric (d) || iscomplex (d) || any (d < 0 | d != fix (d)))
71 error ("dec2base: input must be real non-negative integers");
74 symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
77 base = length (symbols);
78 if (length (unique (symbols)) != base)
79 error ("dec2base: symbols representing digits must be unique");
81 if (any (isspace (symbols)))
82 error ("dec2base: whitespace characters are not valid symbols");
84 elseif (! isscalar (base))
85 error ("dec2base: cannot convert from several bases at once");
86 elseif (base < 2 || base > length (symbols))
87 error ("dec2base: BASE must be between 2 and 36, or a string of symbols");
90 ## determine number of digits required to handle all numbers, can overflow
92 max_len = round (log (max (max (d(:)), 1)) / log (base)) + 1;
95 max_len = max (max_len, len);
98 ## determine digits for each number
99 digits = zeros (length (d), max_len);
101 digits(:,k) = mod (d, base);
102 d = round ((d - digits(:,k)) / base);
105 ## convert digits to symbols
106 retval = reshape (symbols(digits+1), size (digits));
108 ## Check if the first element is the zero symbol. It seems possible
109 ## that LEN is provided, and is less than the computed MAX_LEN and
110 ## MAX_LEN is computed to be one larger than necessary, so we would
111 ## have a leading zero to remove. But if LEN >= MAX_LEN, we should
112 ## not remove any leading zeros.
113 if ((nargin == 2 || (nargin == 3 && max_len > len))
114 && length (retval) != 1 && ! any (retval(:,1) != symbols(1)))
115 retval = retval(:,2:end);
125 %! pp = dec2base (b^n+1, b);
126 %! assert (dec2base(b^n, b), ['1',s0,'0']);
127 %! assert (dec2base(b^n+1, b), ['1',s0,'1']);
133 %! digits='0123456789ABCDEF';
136 %! pm = dec2base(b^n-1, b);
137 %! assert (length (pm), n);
138 %! assert (all (pm==digits(b)));
144 %! assert (dec2base (0, b), '0');
147 %!assert(dec2base (0, 2, 4), "0000");
148 %!assert(dec2base (2^51-1, 2), ...
149 %! '111111111111111111111111111111111111111111111111111');
150 %!assert(dec2base(uint64(2)^63-1, 16), '7FFFFFFFFFFFFFFF');
151 %!assert(dec2base([1, 2; 3, 4], 2, 3), ["001"; "011"; "010"; "100"]);
152 %!assert(dec2base({1, 2; 3, 4}, 2, 3), ["001"; "011"; "010"; "100"]);
154 %%Test input validation
157 %!error dec2base (1, 2, 3, 4)
158 %!error dec2base ("A")
159 %!error dec2base (2i)
160 %!error dec2base (-1)
161 %!error dec2base (1.1)
162 %!error dec2base (1, "ABA")
163 %!error dec2base (1, "A B")
164 %!error dec2base (1, ones(2))
165 %!error dec2base (1, 1)
166 %!error dec2base (1, 37)