# HG changeset patch # User Mike Miller # Date 1375658329 14400 # Node ID 81d3c440964516c218e79fd344d7aa3740a39315 # Parent abf384f5d2438e2a0c6eb4db5215fd6094e70c13 num2hex: Handle single precision argument correctly (bug #39607) * hex2num.cc (Fnum2hex): Handle single precision argument correctly for Matlab compatibility. Update docstring to describe the new behavior. Add test case. diff --git a/libinterp/corefcn/hex2num.cc b/libinterp/corefcn/hex2num.cc --- a/libinterp/corefcn/hex2num.cc +++ b/libinterp/corefcn/hex2num.cc @@ -125,18 +125,30 @@ DEFUN (num2hex, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{s} =} num2hex (@var{n})\n\ -Typecast a double precision number or vector to a 16 character hexadecimal\n\ -string of the IEEE 754 representation of the number. For example:\n\ +Typecast a double or single precision number or vector to a 8 or 16\n\ +character hexadecimal string of the IEEE 754 representation of the number.\n\ +For example:\n\ \n\ @example\n\ @group\n\ -num2hex ([-1, 1, e, Inf, NaN, NA])\n\ +num2hex ([-1, 1, e, Inf])\n\ @result{} \"bff0000000000000\n\ 3ff0000000000000\n\ 4005bf0a8b145769\n\ - 7ff0000000000000\n\ - fff8000000000000\n\ - 7ff00000000007a2\"\n\ + 7ff0000000000000\"\n\ +@end group\n\ +@end example\n\ +\n\ +If the argument @var{n} is a single precision number or vector, the returned\n\ +string has a length of 8. For example:\n\ +\n\ +@example\n\ +@group\n\ +num2hex (single ([-1, 1, e, Inf]))\n\ +@result{} \"bf800000\n\ + 3f800000\n\ + 402df854\n\ + 7f800000\"\n\ @end group\n\ @end example\n\ @seealso{hex2num, hex2dec, dec2hex}\n\ @@ -147,14 +159,52 @@ if (nargin != 1) print_usage (); + else if (args(0).is_single_type ()) + { + const FloatColumnVector v (args(0).float_vector_value ()); + + if (! error_state) + { + octave_idx_type nchars = 8; + octave_idx_type nr = v.length (); + charMatrix m (nr, nchars); + const float *pv = v.fortran_vec (); + + for (octave_idx_type i = 0; i < nr; i++) + { + union + { + uint32_t ival; + float dval; + } num; + + num.dval = *pv++; + + for (octave_idx_type j = 0; j < nchars; j++) + { + unsigned char ch = + static_cast (num.ival >> ((nchars - 1 - j) * 4) & 0xF); + if (ch >= 10) + ch += 'a' - 10; + else + ch += '0'; + + m.elem (i, j) = ch; + } + } + + retval = m; + } + } else { const ColumnVector v (args(0).vector_value ()); if (! error_state) { + octave_idx_type nchars = 16; octave_idx_type nr = v.length (); - charMatrix m (nr, 16); + charMatrix m (nr, nchars); const double *pv = v.fortran_vec (); for (octave_idx_type i = 0; i < nr; i++) @@ -167,10 +217,10 @@ num.dval = *pv++; - for (octave_idx_type j = 0; j < 16; j++) + for (octave_idx_type j = 0; j < nchars; j++) { unsigned char ch = - static_cast (num.ival >> ((15 - j) * 4) & 0xF); + static_cast (num.ival >> ((nchars - 1 - j) * 4) & 0xF); if (ch >= 10) ch += 'a' - 10; else @@ -189,4 +239,5 @@ /* %!assert (num2hex (-2:2), ["c000000000000000";"bff0000000000000";"0000000000000000";"3ff0000000000000";"4000000000000000"]) +%!assert (num2hex (single (-2:2)), ["c0000000";"bf800000";"00000000";"3f800000";"40000000"]) */