12 #include "cln/integer.h"
18 const cl_I mkf_extract (const cl_I& x, uintL p, uintL q)
21 var const uintD* MSDptr;
23 var const uintD* LSDptr;
24 I_to_NDS_nocopy(x, MSDptr=,len=,LSDptr=,cl_true, { return 0; } ); // NDS zu x bilden
25 // MSDptr erhöhen und len erniedrigen, so daß len = ceiling(q/intDsize) wird:
26 { var uintL qD = ceiling(q,intDsize); // ceiling(q/intDsize)
27 // wegen q<=l ist qD = ceiling(q/intDsize) <= ceiling((l+1)/intDsize) = len, also
28 // paßt qD ebenso wie len in ein uintC.
29 MSDptr = MSDptr mspop ((uintL)len - qD); // MSDptr um len-qD Digits erhöhen
30 len = qD; // len um len-qD erniedrigen
32 // Platz (len Digits) für die neue UDS bereitstellen:
34 num_stack_alloc_1((uintL)len, newMSDptr = ,); // Platz belegen
35 {var uintL pD = p/intDsize; // floor(p/intDsize), paßt in ein uintC
36 // Kopiere len-pD Digits aus der DS zu x heraus:
37 var uintD* midptr = copy_loop_msp(MSDptr,newMSDptr,len-(uintC)pD);
38 // Lösche p-intDsize*floor(p/intDsize) Bits im Digit unterhalb von midptr:
39 {var uintL p_D = p%intDsize;
40 if (!(p_D==0)) { lspref(midptr,0) &= minus_bit(p_D); }
42 // Lösche pD Digits darüber:
43 clear_loop_msp(midptr,pD);
45 // Lösche intDsize*ceiling(q/intDsize)-q Bits im ersten Digit:
46 {var uintL q_D = q%intDsize;
48 { mspref(newMSDptr,0) &= (uintD)((1L<<q_D)-1); } // intDsize-q_D Bits löschen
50 // Jetzt enthält die UDS newMSDptr/len/.. die extrahierten Bits.
51 return UDS_to_I(newMSDptr,len);