Mercurial > hg > octave-nkf
changeset 17392: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)