]> www.ginac.de Git - cln.git/blob - src/integer/bitwise/cl_I_ldbx.cc
* */*: Remove cl_boolean, cl_true, and cl_false in favor of built-in
[cln.git] / src / integer / bitwise / cl_I_ldbx.cc
1 // ldb_extract().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_I_byte.h"
8
9
10 // Implementation.
11
12 #include "cln/integer.h"
13 #include "cl_I.h"
14 #include "cl_DS.h"
15
16 namespace cln {
17
18 const cl_I ldb_extract (const cl_I& x, uintC p, uintC q)
19     { CL_ALLOCA_STACK;
20       var const uintD* MSDptr;
21       var uintC len;
22       var const uintD* LSDptr;
23       I_to_NDS_nocopy(x, MSDptr=,len=,LSDptr=,true, { return 0; } ); // NDS zu x bilden
24       // MSDptr erhöhen und len erniedrigen, so daß len = ceiling(q/intDsize) wird:
25       { var uintC qD = ceiling(q,intDsize); // ceiling(q/intDsize)
26         // wegen q<=l ist qD = ceiling(q/intDsize) <= ceiling((l+1)/intDsize) = len, also
27         // paßt qD ebenso wie len in ein uintC.
28         MSDptr = MSDptr mspop (len - qD); // MSDptr um len-qD Digits erhöhen
29         len = qD; // len um len-qD erniedrigen
30       }
31       // LSDptr und len um floor(p/intDsize) erniedrigen:
32       { var uintC pD = floor(p,intDsize); // floor(p/intDsize)
33         LSDptr = LSDptr lspop pD;
34         len -= pD;
35       }
36       // Jetzt enthält MSDptr/len/LSDptr genau die maßgeblichen Digits.
37       var uintD* newMSDptr;
38       { var uintL i = p%intDsize; // p mod intDsize
39         // Kopiere sie und schiebe sie dabei um i Bits nach rechts:
40         num_stack_alloc_1(len, newMSDptr=,); // neue UDS newMSDptr/len/..
41         if (i==0)
42           { copy_loop_msp(MSDptr,newMSDptr,len); }
43           else
44           { shiftrightcopy_loop_msp(MSDptr,newMSDptr,len,i,0); }
45       }
46       // newMSDptr/len/.. = geschobene Kopie der maßgeblichen Digits
47       // Ausblenden der Bits mit Nummern >= q-p:
48       { var uintC bitcount = intDsize*len - (q-p);
49         // Anzahl vorne auszublendender Bits ( >=0, <= intDsize-1 + intDsize-1 )
50         if (bitcount>=intDsize)
51           { bitcount -= intDsize; msshrink(newMSDptr); len -= 1; } // intDsize Bits ausblenden
52         // Noch 0 <= bitcount < intDsize Bits auszublenden:
53         if (bitcount > 0)
54           { mspref(newMSDptr,0) &= (uintD)(bit(intDsize-bitcount)-1); }
55       }
56       // Jetzt enthält die UDS newMSDptr/len/.. die extrahierten Bits.
57       return UDS_to_I(newMSDptr,len); // UDS in Integer umwandeln
58     }
59
60 }  // namespace cln