]> Creatis software - CreaPhase.git/blob - octave_packages/m/strings/dec2base.m
update packages
[CreaPhase.git] / octave_packages / m / strings / dec2base.m
1 ## Copyright (C) 2000-2012 Daniel Calvelo
2 ##
3 ## This file is part of Octave.
4 ##
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.
9 ##
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.
14 ##
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/>.
18
19 ## -*- texinfo -*-
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}.
24 ##
25 ## @example
26 ## @group
27 ## dec2base (123, 3)
28 ##    @result{} "11120"
29 ## @end group
30 ## @end example
31 ##
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 
34 ## the largest value.
35 ##
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
38 ## as a symbol.
39 ##
40 ## @example
41 ## @group
42 ## dec2base (123, "aei")
43 ##    @result{} "eeeia"
44 ## @end group
45 ## @end example
46 ##
47 ## The optional third argument, @var{len}, specifies the minimum
48 ## number of digits in the result.
49 ## @seealso{base2dec, dec2bin, dec2hex}
50 ## @end deftypefn
51
52 ## Author: Daniel Calvelo <dcalvelo@yahoo.com>
53 ## Adapted-by: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
54
55 function retval = dec2base (d, base, len)
56
57   if (nargin < 2 || nargin > 3)
58     print_usage ();
59   endif
60
61   if (iscell (d))
62     d = cell2mat (d);
63   endif
64
65   # Create column vector for algorithm
66   if (! iscolumn (d))
67     d = d(:);
68   endif
69
70   if (! isnumeric (d) || iscomplex (d) || any (d < 0 | d != fix (d)))
71     error ("dec2base: input must be real non-negative integers");
72   endif
73
74   symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
75   if (ischar (base))
76     symbols = base;
77     base = length (symbols);
78     if (length (unique (symbols)) != base)
79       error ("dec2base: symbols representing digits must be unique");
80     endif
81     if (any (isspace (symbols)))
82       error ("dec2base: whitespace characters are not valid symbols");
83     endif
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");
88   endif
89
90   ## determine number of digits required to handle all numbers, can overflow
91   ## by 1 digit
92   max_len = round (log (max (max (d(:)), 1)) / log (base)) + 1;
93
94   if (nargin == 3)
95     max_len = max (max_len, len);
96   endif
97
98   ## determine digits for each number
99   digits = zeros (length (d), max_len);
100   for k = max_len:-1:1
101     digits(:,k) = mod (d, base);
102     d = round ((d - digits(:,k)) / base);
103   endfor
104
105   ## convert digits to symbols
106   retval = reshape (symbols(digits+1), size (digits));
107
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);
116   endif
117
118 endfunction
119
120
121 %!test
122 %! s0 = '';
123 %! for n = 1:13
124 %!   for b = 2:16
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']);
128 %!   endfor
129 %!   s0 = [s0,'0'];
130 %! endfor
131
132 %!test
133 %! digits='0123456789ABCDEF';
134 %! for n = 1:13
135 %!   for b = 2:16
136 %!     pm = dec2base(b^n-1, b);
137 %!     assert (length (pm), n);
138 %!     assert (all (pm==digits(b)));
139 %!   endfor
140 %! endfor
141
142 %!test
143 %! for b = 2:16
144 %!   assert (dec2base (0, b), '0');
145 %! endfor
146
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"]);
153
154 %%Test input validation
155 %!error dec2base ()
156 %!error dec2base (1)
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)
167