changeset 904:dd4242ff0fa4

imcomplement: increased performance for complement of signed integers.
author Carnë Draug <carandraug@octave.org>
date Mon, 13 Oct 2014 16:58:11 +0100
parents 0d49dd1a084c
children 0219144c2c21
files inst/imcomplement.m
diffstat 1 files changed, 11 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/inst/imcomplement.m
+++ b/inst/imcomplement.m
@@ -49,19 +49,18 @@
     B = 1 - A;
   elseif (islogical (A))
     B = ! A;
-  elseif (any (isa (A, {"int8", "int16", "int32", "int64"})))
-    ## Signed integers are different. We have all this extra work to avoid
-    ## conversion into another class which may not fit in memory. And seems
-    ## like it it still performs faster.
-    cl = class (A);
-    B = zeros (size (A), cl);
-    m = (A != intmin (cl));
-
-    B(! m) = intmax (cl);
-    B(m)   = -A -1;
-
   elseif (isinteger (A))
-    B = intmax (class (A)) - A;
+    if (intmin (class (A)) < 0)
+      ## for signed integers, we use bitcmp
+      ## TODO: bitcmp is broken in core (but fixed on 79d4783a9978). Replace
+      ##       with bitcmp once we are dependent on that Octave version
+      nbits = sizeof (A) / numel (A) * 8;
+      B = bitxor (A, bitpack (true (nbits, 1), class (A)));
+    else
+      ## this is currently more efficient than bitcmp (but hopefully core
+      ## will change)
+      B = intmax (class (A)) - A;
+    endif
   else
     error("imcomplement: A must be an image but is of class `%s'", class (A));
   endif