Mercurial > octave
comparison scripts/strings/dec2bin.m @ 28236:5bb1c0cbb27e
dec2bin.m: Allow negative number inputs (bug #58147).
* dec2bin.m: Document that negative numbers are converted according to 2's
complement convention. Add example to documentation of converting a
negative number. Add algorithm to detect negative inputs and add the
appropriate offset for 2's complement notation. Add BIST tests.
author | Nicholas R. Jankowski <jankowskin@asme.org> |
---|---|
date | Wed, 22 Apr 2020 15:53:51 -0700 |
parents | 9f9ac219896d |
children | ac3a078e688f |
comparison
equal
deleted
inserted
replaced
28235:a6edb8097ec6 | 28236:5bb1c0cbb27e |
---|---|
23 ## | 23 ## |
24 ######################################################################## | 24 ######################################################################## |
25 | 25 |
26 ## -*- texinfo -*- | 26 ## -*- texinfo -*- |
27 ## @deftypefn {} {} dec2bin (@var{d}, @var{len}) | 27 ## @deftypefn {} {} dec2bin (@var{d}, @var{len}) |
28 ## Return a binary number corresponding to the non-negative integer @var{d}, | 28 ## Return a binary number corresponding to the integer @var{d} as a string of |
29 ## as a string of ones and zeros. | 29 ## ones and zeros. If @var{d} is negative, return the two's complement binary |
30 ## value of @var{d}. | |
30 ## | 31 ## |
31 ## For example: | 32 ## For example: |
32 ## | 33 ## |
33 ## @example | 34 ## @example |
34 ## @group | 35 ## @group |
35 ## dec2bin (14) | 36 ## dec2bin (14) |
36 ## @result{} "1110" | 37 ## @result{} "1110" |
38 ## | |
39 ## dec2bin (-14) | |
40 ## @result{} "11110010" | |
37 ## @end group | 41 ## @end group |
38 ## @end example | 42 ## @end example |
39 ## | 43 ## |
40 ## If @var{d} is a matrix or cell array, return a string matrix with one row | 44 ## If @var{d} is a matrix or cell array, return a string matrix with one row |
41 ## per element in @var{d}, padded with leading zeros to the width of the | 45 ## per element in @var{d}, padded with leading zeros to the width of the |
42 ## largest value. | 46 ## largest value. |
43 ## | 47 ## |
44 ## The optional second argument, @var{len}, specifies the minimum number of | 48 ## The optional second argument, @var{len}, specifies the minimum number of |
45 ## digits in the result. | 49 ## digits in the result. |
50 ## | |
46 ## @seealso{bin2dec, dec2base, dec2hex} | 51 ## @seealso{bin2dec, dec2base, dec2hex} |
47 ## @end deftypefn | 52 ## @end deftypefn |
48 | 53 |
49 function b = dec2bin (d, len) | 54 function b = dec2bin (d, len) |
55 | |
56 ## dec2base does cell->mat conversion, this allows easier content comparison | |
57 if (iscell (d)) | |
58 d = cell2mat (d); | |
59 endif | |
60 | |
61 d = d(:); ## output is always a column vector, (:) simplifies value checks | |
62 | |
63 if (any (d < intmin ("int64"))) | |
64 error ("dec2bin: negative inputs cannot be less than intmin('int64')"); | |
65 endif | |
66 | |
67 if (any (d < 0)) | |
68 if (any (d < intmin ("int64"))) | |
69 error ("out of range"); | |
70 elseif (any (d < intmin ("int32"))) | |
71 d(d < 0) += double (intmax ("uint64")) + 1 ; | |
72 elseif (any (d < intmin ("int16"))) | |
73 d(d < 0) += double (intmax ("uint32")) + 1; | |
74 elseif (any (d < intmin ("int8"))) | |
75 d(d < 0) += double (intmax ("uint16"))+ 1; | |
76 else | |
77 d(d < 0) += double (intmax ("uint8")) +1; | |
78 endif | |
79 endif | |
50 | 80 |
51 if (nargin == 1) | 81 if (nargin == 1) |
52 b = dec2base (d, 2); | 82 b = dec2base (d, 2); |
53 elseif (nargin == 2) | 83 elseif (nargin == 2) |
54 b = dec2base (d, 2, len); | 84 b = dec2base (d, 2, len); |
57 endif | 87 endif |
58 | 88 |
59 endfunction | 89 endfunction |
60 | 90 |
61 | 91 |
92 %!assert (dec2bin (3), "11") | |
62 %!assert (dec2bin (14), "1110") | 93 %!assert (dec2bin (14), "1110") |
63 %!assert (dec2bin (14, 6), "001110") | 94 %!assert (dec2bin (14, 6), "001110") |
95 %!assert (dec2bin ([1, 2; 3, 4]), ["001"; "011"; "010"; "100"]) | |
64 %!assert (dec2bin ({1, 2; 3, 4}), ["001"; "011"; "010"; "100"]) | 96 %!assert (dec2bin ({1, 2; 3, 4}), ["001"; "011"; "010"; "100"]) |
97 %!assert (dec2bin ({1, 2; 3, 4}, 4), ["0001"; "0011"; "0010"; "0100"]) | |
98 | |
99 ## Test negative inputs | |
100 %!assert (dec2bin (-3), "11111101") | |
101 %!assert (dec2bin (-3, 3), "11111101") | |
102 %!assert (dec2bin (-3, 9), "011111101") | |
103 %!assert (dec2bin (-129), "1111111101111111") | |
104 %!assert (dec2bin (-2^15 -1), "11111111111111110111111111111111") | |
105 %!assert (dec2bin (-2^31 -1), "1111111111111111111111111111111101111111111111111111111111111111") | |
106 %!assert (dec2bin (-2^63), "1000000000000000000000000000000000000000000000000000000000000000") | |
107 %!assert (dec2bin (-2^63-1), "1000000000000000000000000000000000000000000000000000000000000000") | |
108 %!assert (dec2bin ([-1, -2; -3, -4]), ["11111111"; "11111101"; "11111110"; "11111100"]) | |
109 %!assert (dec2bin ([1, 2; 3, -4]), ["00000001"; "00000011"; "00000010"; "11111100"]) | |
110 %!assert (dec2bin ({1, 2; 3, -4}), ["00000001"; "00000011"; "00000010"; "11111100"]) | |
65 | 111 |
66 ## Test input validation | 112 ## Test input validation |
67 %!error dec2bin () | 113 %!error dec2bin () |
68 %!error dec2bin (1, 2, 3) | 114 %!error dec2bin (1, 2, 3) |
115 %!error dec2bin (2 * double (intmin ("int64"))) |