Mercurial > octave
diff scripts/strings/dec2hex.m @ 31848:1f3f7e874203
dec2base.m: Accept negative and fractional inputs (bug #63282)
Previously only dec2bin and dec2hex accepted negative inputs but not
dec2base, which led to inconsistency and repeated code. This changeset
centralizes the negative input functionality in dec2base, and eliminates
that code in the other functions. It also adds the ability to accept
fractional inputs in dec2base.
dec2base.m: Add new functionality to handle negative inputs and
fractional inputs. Update BISTs. Add documentation.
dec2bin.m: Remove code to handle negative inputs. Pass through to dec2base.
Add code for padding the output to Matlab-compatible sizes. Update BISTs.
Add documentation.
dec2base.m: Remove a matrix indexing bug. Pass through to dec2bin.
Update BISTs. Add documentation.
NEWS.9.md: Add note about new functionality.
author | Arun Giridhar <arungiridhar@gmail.com> |
---|---|
date | Fri, 24 Feb 2023 12:45:21 -0500 |
parents | 597f3ee61a48 |
children | a098cc74d9a5 |
line wrap: on
line diff
--- a/scripts/strings/dec2hex.m Fri Feb 24 09:36:30 2023 -0500 +++ b/scripts/strings/dec2hex.m Fri Feb 24 12:45:21 2023 -0500 @@ -29,8 +29,8 @@ ## Return a string representing the conversion of the integer @var{d} to a ## hexadecimal (base16) number. ## -## If @var{d} is negative, return the hexadecimal equivalent of the two's -## complement binary value of @var{d}. +## If @var{d} is negative, return the hexadecimal complement of @var{d}. +## ## If @var{d} is a matrix or cell array, return a string matrix with one row ## for each element in @var{d}, padded with leading zeros to the width of the ## largest value. @@ -50,6 +50,11 @@ ## @end group ## @end example ## +## Programming tip: @code{dec2hex} discards any fractional part of the input. +## If you need the fractional part to be converted too, call @code{dec2base} +## with a non-zero number of decimal places. You can also use @code{fix} or +## @code{round} on fractional inputs to ensure predictable rounding behavior. +## ## @seealso{hex2dec, dec2base, dec2bin} ## @end deftypefn @@ -59,24 +64,40 @@ print_usage (); endif - ## To avoid repeating a lot of code, including input validation, we call dec2bin. + if (iscell (d)) + d = cell2mat (d); + endif + d = d(:); + + neg = (d < 0); + if (nargin == 2) d = dec2bin (d, len*4); else d = dec2bin (d); endif - ## Left-pad with zeros to make the number of columns divisible by 4 + ## Left-pad to a multiple of 4 columns. n = mod (columns (d), 4); if (n > 0) - d = [repmat("0", rows(d), 4-n), d]; + tmp = "01"(neg + 1); # leftpad with "0" for positive, "1" for negative + d = [repmat(tmp(:), 1, 4 - n), d]; endif - d -= "0"; # convert to numeric + d -= '0'; # convert to numeric d = d(:, 1:4:end) * 8 + d(:, 2:4:end) * 4 + d(:, 3:4:end) * 2 + d(:, 4:4:end); - ## Elements of d are now in the range 0 to 15 + ## Elements of d are now in the range 0 to 15. - hstr = "0123456789ABCDEF"(d+1); # convert to char and return + ## Convert to char matrix and return. + ## We used to return this in a single line: + ## hstr = ("0123456789ABCDEF")(d+1); + ## But there are edge cases governing the sizes of row and column vectors + ## that cause problems with output size, so we use a loop instead. + hstr = repmat (' ', size (d)); + v = "0123456789ABCDEF"; + for t = 0:15 + hstr(d == t) = v(t + 1); + endfor endfunction @@ -90,7 +111,7 @@ ## Test negative inputs %!assert (dec2hex (-3), "FD") %!assert (dec2hex (-3, 1), "FD") -%!assert (dec2hex (-3, 3), "0FD") +%!assert (dec2hex (-3, 3), "FFD") %!assert (dec2hex (-2^7 - 1), "FF7F") %!assert (dec2hex (-2^15 - 1), "FFFF7FFF") %!assert (dec2hex (-2^31 - 1), "FFFFFFFF7FFFFFFF") @@ -103,6 +124,12 @@ %!assert (dec2hex ([1, 2; 3, -4]), ["01"; "03"; "02"; "FC"]) %!assert (dec2hex ({1, 2; 3, -4}), ["01"; "03"; "02"; "FC"]) +## Test that the output is of the correct size. +## Next line should return a column vector: +%!assert (dec2hex (0:15), "0123456789ABCDEF"(:)) +## Next line should return a row vector: +%!assert (dec2hex (uint64 (18364758544493064720)), "FEDCBA9876543210") + ## Test input validation %!error <Invalid call> dec2hex ()