changeset 17177:81d3c4409645

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.
author Mike Miller <mtmiller@ieee.org>
date Sun, 04 Aug 2013 19:18:49 -0400
parents abf384f5d243
children f010db8b710c
files libinterp/corefcn/hex2num.cc
diffstat 1 files changed, 60 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/hex2num.cc	Sun Aug 04 18:13:08 2013 -0700
+++ b/libinterp/corefcn/hex2num.cc	Sun Aug 04 19:18:49 2013 -0400
@@ -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<char> (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<char> (num.ival >> ((15 - j) * 4) & 0xF);
+                    static_cast<char> (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"])
 */