# HG changeset patch # User Rik # Date 1587850269 25200 # Node ID f618edac2a294320f35b8781bb5631d72ea0589e # Parent ef7bc64a604b6ca1f444cf3682d07ebc35fa4e39 dec2hex.m: Implement support for negative number inputs (bug #58147). * dec2hex.m: Update documentation to mention support for negative numbers. Copy algorithm from dec2bin.m, but replace final call to dec2base (d,2) with dec2base (d, 16). Add new BIST tests. diff -r ef7bc64a604b -r f618edac2a29 scripts/strings/dec2hex.m --- a/scripts/strings/dec2hex.m Sat Apr 25 11:45:03 2020 -0700 +++ b/scripts/strings/dec2hex.m Sat Apr 25 14:31:09 2020 -0700 @@ -24,36 +24,66 @@ ######################################################################## ## -*- texinfo -*- -## @deftypefn {} {} dec2hex (@var{d}, @var{len}) -## Return the hexadecimal string corresponding to the non-negative integer -## @var{d}. +## @deftypefn {} {} dec2hex (@var{d}) +## @deftypefnx {} {} dec2hex (@var{d}, @var{len}) +## Return a string representing the conversion of the integer @var{d} to a +## hexadecimal (base16) number. ## -## For example: +## If @var{d} is negative, return the two's complement binary value 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. +## +## The optional second argument, @var{len}, specifies the minimum number of +## digits in the result. +## +## Examples: ## ## @example ## @group ## dec2hex (2748) ## @result{} "ABC" +## +## dec2hex (-2) +## @result{} "FE" ## @end group ## @end example ## -## If @var{d} is a matrix or cell array, return a string matrix with one row -## per element in @var{d}, padded with leading zeros to the width of the -## largest value. -## -## The optional second argument, @var{len}, specifies the minimum number of -## digits in the result. ## @seealso{hex2dec, dec2base, dec2bin} ## @end deftypefn function h = dec2hex (d, len) + if (nargin == 0 || nargin > 2) + print_usage (); + endif + + if (iscell (d)) + d = cell2mat (d); + endif + ## Create column vector for algorithm (output is always col. vector anyways) + d = d(:); + + lt_zero_idx = (d < 0); + if (any (lt_zero_idx)) + ## FIXME: Need an algorithm that works with larger values such as int64. + if (any (d(lt_zero_idx) < -2^52)) + error ("dec2hex: negative inputs cannot be less than -flintmax () / 2"); + elseif (any (d(lt_zero_idx) < intmin ("int32"))) + d(lt_zero_idx) += flintmax (); + elseif (any (d < intmin ("int16"))) + d(lt_zero_idx) += double (intmax ("uint32")) + 1; + elseif (any (d < intmin ("int8"))) + d(lt_zero_idx) += double (intmax ("uint16"))+ 1; + else + d(lt_zero_idx) += double (intmax ("uint8")) + 1; + endif + endif + if (nargin == 1) h = dec2base (d, 16); - elseif (nargin == 2) + else h = dec2base (d, 16, len); - else - print_usage (); endif endfunction @@ -61,8 +91,37 @@ %!assert (dec2hex (2748), "ABC") %!assert (dec2hex (2748, 5), "00ABC") +%!assert (dec2hex ([2748, 2746]), ["ABC"; "ABA"]) %!assert (dec2hex ({2748, 2746}), ["ABC"; "ABA"]) +%!assert (dec2hex ({2748, 2746}, 4), ["0ABC"; "0ABA"]) + +## Test negative inputs +%!assert (dec2hex (-3), "FD") +%!assert (dec2hex (-3, 1), "FD") +%!assert (dec2hex (-3, 3), "0FD") +%!assert (dec2hex (-2^7 -1), "FF7F") +%!assert (dec2hex (-2^15 -1), "FFFF7FFF") +## FIXME: Matlab returns longer string that begins with 'F' +%!assert (dec2hex (-2^31 -1), "1FFFFF7FFFFFFF") +## FIXME: Matlab returns longer string that begins with 'FFF' +%!assert (dec2hex (-2^52), "10000000000000") +## FIXME: Uncomment when support for int64 is added +%!#assert (dec2hex (-2^63), +%! "1000000000000000000000000000000000000000000000000000000000000000") +%!#test +%! assert (dec2hex (int64 (-2^63)), +%! "1000000000000000000000000000000000000000000000000000000000000000"); +%!#test +%! assert (dec2hex (int64 (-2^63) -1), +%! "1000000000000000000000000000000000000000000000000000000000000000"); +%!#test +%! assert (dec2hex (int64 (-2^63) +1), +%! "1000000000000000000000000000000000000000000000000000000000000001"); +%!assert (dec2hex ([-1, -2; -3, -4]), ["FF"; "FD"; "FE"; "FC"]) +%!assert (dec2hex ([1, 2; 3, -4]), ["01"; "03"; "02"; "FC"]) +%!assert (dec2hex ({1, 2; 3, -4}), ["01"; "03"; "02"; "FC"]) ## Test input validation %!error dec2hex () %!error dec2hex (1, 2, 3) +%!error dec2hex (- flintmax ())