4 #include "base/cl_sysdep.h"
7 #include "cln/integer.h"
12 #include "integer/cl_I.h"
13 #include "base/digitseq/cl_DS.h"
17 const cl_I ash (const cl_I& x, sintC y)
20 // x = 0 -> 0 als Ergebnis
21 // y = 0 -> x als Ergebnis
22 // y > 0 -> y = intDsize*k + i, j=k+(1 falls i>0, 0 falls i=0).
23 // j Wörter mehr reservieren, k Nullwörter, dann übertragen,
24 // bei i>0: um i Bits links schieben (i=1 geht einfacher).
25 // y < 0 -> y <= - intDsize * (Länge(A0) in Digits) -> Ergebnis = 0 oder -1.
26 // Sonst: -y = intDsize*k + i mit k<Länge(A0).
27 // Übertrage die (Länge(A0)-k) MSDigits,
28 // falls i>0: schiebe sie um i Bits nach rechts (i=1 geht einfacher).
30 return 0; // x=0 -> 0 als Ergebnis
32 return x; // y=0 -> x als Ergebnis
36 var uintC y_ = (uintC)y;
37 var uintL i = y_%intDsize; // i = y mod intDsize, >=0, <intDsize
38 var uintC k = floor(y_,intDsize); // k = y div intDsize, >=0, <2^intCsize
41 var const uintD* x_LSDptr;
42 I_to_NDS_nocopy(x, ,len=,x_LSDptr=,false,); // DS zu x bilden.
43 if (k >= (uintC)(~len)) // kann len+k+1 Überlauf geben?
44 { throw ash_exception(y); } // ja -> Fehler
45 num_stack_alloc_1(len+k,,LSDptr=);
46 LSDptr = clear_loop_lsp(LSDptr,k); // k Nulldigits
47 {var uintD* MSDptr = copy_loop_lsp(x_LSDptr,LSDptr,len);
48 // Nun ist MSDptr/len/LSDptr die DS zu x.
49 // Oberhalb von ihr liegen k Nulldigits, unterhalb ist 1 Digit Platz.
50 // MSDptr/len+k/.. ist jetzt die Gesamt-DS.
51 // Noch um i Bits nach links schieben:
52 if (!(i==0)) // Bei i>0
53 { // noch ein weiteres Digit dazunehmen (Vorzeichen)
54 {var uintD sign = sign_of_sintD(mspref(MSDptr,0));
55 lsprefnext(MSDptr) = sign;
58 // Schiebeschleife: die unteren len Digits um i Bits schieben
60 { shift1left_loop_lsp(LSDptr,len); }
62 { shiftleft_loop_lsp(LSDptr,len,i,0); }
64 return DS_to_I(MSDptr,len+k);
68 var uintC y_ = (uintC)(-y); // Wert von -y, >0
69 var uintL i = y_%intDsize; // i = (-y) mod intDsize, >=0, <intDsize
70 var uintC k = floor(y_,intDsize); // k = (-y) div intDsize, >=0
74 I_to_NDS(x, MSDptr=,len=,); // DS zu x bilden.
75 if (k>=len) goto sign; // -y >= intDsize*len -> Vorzeichen von x zurück
76 len -= k; // rechte k Digits einfach streichen
77 // Noch ist len>0. Um i Bits nach rechts schieben:
78 if (!(i==0)) // Bei i>0:
79 { // Schiebe len Digits ab MSDptr um i Bits nach rechts:
81 { shift1right_loop_msp(MSDptr,len,sign_of_sintD(mspref(MSDptr,0))); }
83 { shiftrightsigned_loop_msp(MSDptr,len,i); }
85 return DS_to_I(MSDptr,len);
87 sign: // Ergebnis ist 0, falls x>=0, und -1, falls x<0:
88 return (minusp(x) ? cl_I(-1) : cl_I(0));