]> www.ginac.de Git - cln.git/blob - src/integer/bitwise/cl_I_lognand.cc
2b4bd6fe9ee10dbf2a6f3361fe06e39eed5d7090
[cln.git] / src / integer / bitwise / cl_I_lognand.cc
1 // lognand().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_integer.h"
8
9
10 // Implementation.
11
12 #include "cl_I.h"
13 #include "cl_DS.h"
14 #include "cl_I_log.h"
15
16 // Logische Operationen auf Integers:
17 // Methode: aus den Längen der beiden Argumente eine obere Schranke für
18 // die Länge des Ergebnisses berechnen (das Maximum der beiden Längen und
19 // FN_maxlength), so daß das MSD für unendlich viele Bits steht.
20 // Dann beide Argumente in gleichgroße Digit sequences umwandeln, Operation
21 // mit einer einfachen Schleife durchführen.
22
23 const cl_I lognand (const cl_I& x, const cl_I& y)
24     { if (fixnump(x) && fixnump(y)) // Beides Fixnums -> ganz einfach:
25         { // bitweise als Fixnum zurück
26           return cl_I_from_word((x.word & y.word) ^ cl_combine(0,~(cl_uint)0));
27         }
28       if (fixnump(x))
29         { DeclareType(cl_FN,x);
30           if (!minusp(x))
31             // PosFixnum AND Bignum -> PosFixnum
32             { return cl_I_from_word((x.word & cl_combine(0,pFN_maxlength_digits_at(BN_LSDptr(y)))) ^ cl_combine(cl_FN_tag,~(cl_uint)0)); }
33         }
34       if (fixnump(y))
35         { DeclareType(cl_FN,y);
36           if (!minusp(y))
37             // Bignum AND PosFixnum -> PosFixnum
38             { return cl_I_from_word((cl_combine(0,pFN_maxlength_digits_at(BN_LSDptr(x))) & y.word) ^ cl_combine(cl_FN_tag,~(cl_uint)0)); }
39         }
40       { CL_ALLOCA_STACK;
41         var uintC n; // Anzahl der Digits
42        {var uintC nx = I_to_DS_need(x);
43         var uintC ny = I_to_DS_need(y);
44         n = (nx>=ny ? nx : ny);
45        }
46        {var uintD* xptr; I_to_DS_n(x,n,xptr=); // Pointer in DS zu x
47         var uintD* yptr; I_to_DS_n(y,n,yptr=); // Pointer in DS zu y
48         var uintD* zptr = xptr; // Pointer aufs Ergebnis
49         nand_loop_msp(xptr,yptr,n); // mit NOT AND verknüpfen
50         return DS_to_I(zptr,n); // Ergebnis als Integer
51     } }}