12 #include "cln/integer.h"
18 const cl_I ldb_extract (const cl_I& x, uintL p, uintL q)
20 var const uintD* MSDptr;
22 var const uintD* LSDptr;
23 I_to_NDS_nocopy(x, MSDptr=,len=,LSDptr=,cl_true, { return 0; } ); // NDS zu x bilden
24 // MSDptr erhöhen und len erniedrigen, so daß len = ceiling(q/intDsize) wird:
25 { var uintL 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 ((uintL)len - qD); // MSDptr um len-qD Digits erhöhen
29 len = qD; // len um len-qD erniedrigen
31 // LSDptr und len um floor(p/intDsize) erniedrigen:
32 { var uintL pD = floor(p,intDsize); // floor(p/intDsize)
33 LSDptr = LSDptr lspop pD;
36 // Jetzt enthält MSDptr/len/LSDptr genau die maßgeblichen Digits.
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((uintL)len, newMSDptr=,); // neue UDS newMSDptr/len/..
42 { copy_loop_msp(MSDptr,newMSDptr,len); }
44 { shiftrightcopy_loop_msp(MSDptr,newMSDptr,len,i,0); }
46 // newMSDptr/len/.. = geschobene Kopie der maßgeblichen Digits
47 // Ausblenden der Bits mit Nummern >= q-p:
48 { var uintL bitcount = intDsize*(uintL)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:
54 { mspref(newMSDptr,0) &= (uintD)(bit(intDsize-bitcount)-1); }
56 // Jetzt enthält die UDS newMSDptr/len/.. die extrahierten Bits.
57 return UDS_to_I(newMSDptr,len); // UDS in Integer umwandeln