]> www.ginac.de Git - cln.git/blobdiff - src/integer/bitwise/cl_I_logand.cc
Initial revision
[cln.git] / src / integer / bitwise / cl_I_logand.cc
diff --git a/src/integer/bitwise/cl_I_logand.cc b/src/integer/bitwise/cl_I_logand.cc
new file mode 100644 (file)
index 0000000..e7b4ccc
--- /dev/null
@@ -0,0 +1,51 @@
+// logand().
+
+// General includes.
+#include "cl_sysdep.h"
+
+// Specification.
+#include "cl_integer.h"
+
+
+// Implementation.
+
+#include "cl_I.h"
+#include "cl_DS.h"
+#include "cl_I_log.h"
+
+// Logische Operationen auf Integers:
+// Methode: aus den Längen der beiden Argumente eine obere Schranke für
+// die Länge des Ergebnisses berechnen (das Maximum der beiden Längen und
+// FN_maxlength), so daß das MSD für unendlich viele Bits steht.
+// Dann beide Argumente in gleichgroße Digit sequences umwandeln, Operation
+// mit einer einfachen Schleife durchführen.
+
+const cl_I logand (const cl_I& x, const cl_I& y)
+    { if (fixnump(x) && fixnump(y)) // Beides Fixnums -> ganz einfach:
+        { // bitweise als Fixnum zurück
+          return cl_I_from_word(x.word & y.word);
+        }
+      if (fixnump(x))
+        { DeclareType(cl_FN,x);
+          if (!minusp(x))
+            // PosFixnum AND Bignum -> PosFixnum
+            { return cl_I_from_word(x.word & cl_combine(cl_FN_tag,pFN_maxlength_digits_at(BN_LSDptr(y)))); }
+        }
+      if (fixnump(y))
+        { DeclareType(cl_FN,y);
+          if (!minusp(y))
+            // Bignum AND PosFixnum -> PosFixnum
+            { return cl_I_from_word(cl_combine(cl_FN_tag,pFN_maxlength_digits_at(BN_LSDptr(x))) & y.word); }
+        }
+      { CL_ALLOCA_STACK;
+        var uintC n; // Anzahl der Digits
+       {var uintC nx = I_to_DS_need(x);
+        var uintC ny = I_to_DS_need(y);
+        n = (nx>=ny ? nx : ny);
+       }
+       {var uintD* xptr; I_to_DS_n(x,n,xptr=); // Pointer in DS zu x
+        var uintD* yptr; I_to_DS_n(y,n,yptr=); // Pointer in DS zu y
+        var uintD* zptr = xptr; // Pointer aufs Ergebnis
+        and_loop_msp(xptr,yptr,n); // mit AND verknüpfen
+        return DS_to_I(zptr,n); // Ergebnis als Integer
+    } }}