Mercurial > hg > octave-nkf
diff scripts/general/bitcmp.m @ 19444:79d4783a9978
bitcmp: fix bitwise complement for signed integers.
* general/bitcmp.m: current implementation of bitwise complement is broken
for signed integers because it uses intmax() as mask for bitxor(). This is
incorrect because the last bit of a signed integer is 0 and not 1. Fix this
by bitpacking an array of true(). Also simplified input checking by using
sizeof, rather than multiple calls to isa(). Added tests for signed integers.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Mon, 13 Oct 2014 13:40:44 +0100 |
parents | d63878346099 |
children | 4197fc428c7d |
line wrap: on
line diff
--- a/scripts/general/bitcmp.m +++ b/scripts/general/bitcmp.m @@ -31,6 +31,7 @@ ## @result{} 110100 ## @end group ## @end example +## ## @seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax} ## @end deftypefn @@ -52,27 +53,11 @@ elseif (isa (A, "single")) bmax = bitmax ("single"); amax = ceil (log2 (bmax)); + elseif (isinteger (A)) + amax = sizeof (ones (1, class (A))) * 8; + bmax = bitpack (true (amax, 1), class (A)); else - if (isa (A, "uint8")) - amax = 8; - elseif (isa (A, "uint16")) - amax = 16; - elseif (isa (A, "uint32")) - amax = 32; - elseif (isa (A, "uint64")) - amax = 64; - elseif (isa (A, "int8")) - amax = 8; - elseif (isa (A, "int16")) - amax = 16; - elseif (isa (A, "int32")) - amax = 32; - elseif (isa (A, "int64")) - amax = 64; - else - error ("bitcmp: invalid class %s", class (A)); - endif - bmax = intmax (class (A)); + error ("bitcmp: invalid class %s", class (A)); endif if (nargin == 1 || k == amax) @@ -131,3 +116,9 @@ %! assert (bitcmp (A,Amax-1), bitshift (uint64 (1),Amax-2)); %! assert (bitcmp (A,Amax-2), uint64 (0)); +## Do not forget signed integers +%!assert (bitcmp (int8 (127)), int8 (-128)) # [1 1 1 1 1 1 1 0] +%!assert (bitcmp (int8 (1)), int8 (-2)) # [1 0 0 0 0 0 0 0] +%!assert (bitcmp (int8 (0)), int8 (-1)) # [0 0 0 0 0 0 0 0] +%!assert (bitcmp (int8 (8)), int8 (-9)) # [0 0 0 1 0 0 0 0] +