changeset 17409:e09cd91168d1

Support arguments of class single in bit manipulation functions (bug #34502) * bitfcns.cc (bitop, Fbitshift): Support arguments of class single. * bitcmp.m, bitget.m, bitset.m: Support arguments of class single. Add tests.
author Mike Miller <mtmiller@ieee.org>
date Sun, 08 Sep 2013 17:55:40 -0400
parents 7d8d194f3f63
children 6437a6815bc6
files libinterp/corefcn/bitfcns.cc scripts/general/bitcmp.m scripts/general/bitget.m scripts/general/bitset.m
diffstat 4 files changed, 68 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/bitfcns.cc
+++ b/libinterp/corefcn/bitfcns.cc
@@ -38,6 +38,7 @@
 #include "ov-int32.h"
 #include "ov-int16.h"
 #include "ov-int8.h"
+#include "ov-float.h"
 #include "ov-scalar.h"
 #include "ov-re-mat.h"
 #include "ov-bool.h"
@@ -138,25 +139,55 @@
   if (nargin == 2)
     {
       if ((args(0).class_name () == octave_scalar::static_class_name ())
+          || (args(0).class_name () == octave_float_scalar::static_class_name ())
           || (args(0).class_name () == octave_bool::static_class_name ())
           || (args(1).class_name () == octave_scalar::static_class_name ())
+          || (args(1).class_name () == octave_float_scalar::static_class_name ())
           || (args(1).class_name () == octave_bool::static_class_name ()))
         {
           bool arg0_is_int = (args(0).class_name () !=
                               octave_scalar::static_class_name () &&
                               args(0).class_name () !=
+                              octave_float_scalar::static_class_name () &&
+                              args(0).class_name () !=
                               octave_bool::static_class_name ());
           bool arg1_is_int = (args(1).class_name () !=
                               octave_scalar::static_class_name () &&
                               args(1).class_name () !=
+                              octave_float_scalar::static_class_name () &&
+                              args(1).class_name () !=
                               octave_bool::static_class_name ());
+          bool arg0_is_float = args(0).class_name () ==
+                               octave_float_scalar::static_class_name ();
+          bool arg1_is_float = args(1).class_name () ==
+                               octave_float_scalar::static_class_name ();
 
           if (! (arg0_is_int || arg1_is_int))
             {
-              uint64NDArray x (args(0).array_value ());
-              uint64NDArray y (args(1).array_value ());
-              if (! error_state)
-                retval = bitopx (fname, x, y).array_value ();
+              if (! (arg0_is_float || arg1_is_float))
+                {
+                  uint64NDArray x (args(0).array_value ());
+                  uint64NDArray y (args(1).array_value ());
+                  if (! error_state)
+                    retval = bitopx (fname, x, y).array_value ();
+                }
+              else if (arg0_is_float && arg1_is_float)
+                {
+                  uint64NDArray x (args(0).float_array_value ());
+                  uint64NDArray y (args(1).float_array_value ());
+                  if (! error_state)
+                    retval = bitopx (fname, x, y).float_array_value ();
+                }
+              else
+                {
+                  int p = (arg0_is_float ? 1 : 0);
+                  int q = (arg0_is_float ? 0 : 1);
+
+                  uint64NDArray x (args(p).array_value ());
+                  uint64NDArray y (args(q).float_array_value ());
+                  if (! error_state)
+                    retval = bitopx (fname, x, y).float_array_value ();
+                }
             }
           else
             {
@@ -561,6 +592,19 @@
           NDArray m = m_arg.array_value ();
           DO_BITSHIFT ( );
         }
+      else if (cname == "single")
+        {
+          static const int bits_in_mantissa = std::numeric_limits<float>::digits;
+          nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
+          int64_t mask = max_mantissa_value<float> ();
+          if (nbits < bits_in_mantissa)
+            mask = mask >> (bits_in_mantissa - nbits);
+          else if (nbits < 1)
+            mask = 0;
+          int bits_in_type = sizeof (float) * CHAR_BIT;
+          FloatNDArray m = m_arg.float_array_value ();
+          DO_BITSHIFT (Float);
+        }
       else
         error ("bitshift: not defined for %s objects", cname.c_str ());
     }
--- a/scripts/general/bitcmp.m
+++ b/scripts/general/bitcmp.m
@@ -49,6 +49,9 @@
   if (isa (A, "double"))
     bmax = bitmax;
     amax = ceil (log2 (bmax));
+  elseif (isa (A, "single"))
+    bmax = bitmax ("single");
+    amax = ceil (log2 (bmax));
   else
     if (isa (A, "uint8"))
       amax = 8;
@@ -93,6 +96,13 @@
 %! assert (bitcmp (A,Amax-1), bitshift (1,Amax-2));
 %! assert (bitcmp (A,Amax-2), 0);
 %!test
+%! Amax = 24;
+%! Bmax = bitmax ("single");
+%! A = bitshift (Bmax,-2);
+%! assert (bitcmp (A,Amax),bitor (bitshift (single (1),Amax-1), bitshift (single (1),Amax-2)));
+%! assert (bitcmp (A,Amax-1), bitshift (single (1),Amax-2));
+%! assert (bitcmp (A,Amax-2), single (0));
+%!test
 %! Amax = 8;
 %! Bmax = intmax ("uint8");
 %! A = bitshift (Bmax,-2);
--- a/scripts/general/bitget.m
+++ b/scripts/general/bitget.m
@@ -41,6 +41,9 @@
   if (isa (A, "double"))
     Amax = ceil (log2 (bitmax));
     _conv = @double;
+  elseif (isa (A, "single"))
+    Amax = ceil (log2 (bitmax ("single")));
+    _conv = @single;
   else
     if (isa (A, "uint8"))
       Amax = 8;
@@ -83,6 +86,7 @@
 
 %!test
 %! assert (bitget ([4, 14], [3, 3]), logical ([1, 1]));
+%! assert (bitget (single ([4, 14]), [3, 3]), logical ([1, 1]));
 %! pfx = {"", "u"};
 %! for i = 1:2
 %!   for prec = [8, 16, 32, 64]
@@ -94,6 +98,9 @@
 %!error bitget (0, 0)
 %!error bitget (0, 55)
 
+%!error bitget (single (0), 0)
+%!error bitget (single (0), 26)
+
 %!error bitget (int8 (0), 9)
 %!error bitget (uint8 (0), 9)
 
--- a/scripts/general/bitset.m
+++ b/scripts/general/bitset.m
@@ -91,6 +91,7 @@
 
 %!test
 %! assert (bitset ([0, 10], [3, 3]), [4, 14]);
+%! assert (bitset (single ([0, 10]), [3, 3]), single ([4, 14]));
 %! pfx = {"", "u"};
 %! for i = 1:2
 %!   for prec = [8, 16, 32, 64]
@@ -108,6 +109,8 @@
 %!error <invalid class char> bitset ("1", 2)
 %!error <N must be in the range \[1,53\]> bitset (0, 0)
 %!error <N must be in the range \[1,53\]> bitset (0, 55)
+%!error <N must be in the range \[1,24\]> bitset (single (0), 0)
+%!error <N must be in the range \[1,24\]> bitset (single (0), 26)
 %!error <N must be in the range \[1,8\]> bitset (uint8 (0), 0)
 %!error <N must be in the range \[1,8\]> bitset (uint8 (0), 9)
 %!error <N must be in the range \[1,7\]> bitset (int8 (0), 9)