]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_from_NDS.cc
Use paths relative the `src' directory in the #include directives.
[cln.git] / src / integer / conv / cl_I_from_NDS.cc
1 // NDS_to_I().
2
3 // General includes.
4 #include "base/cl_sysdep.h"
5
6 // Specification.
7 #include "integer/cl_I.h"
8
9
10 // Implementation.
11
12 #include "cln/number.h"
13 #include "base/digitseq/cl_DS.h"
14
15 namespace cln {
16
17 CL_INLINE const cl_I CL_INLINE_DECL(NDS_to_I) (const uintD* MSDptr, uintC len)
18 {
19       // Mehr als bn_minlength Digits -> Bignum.
20       // Weniger als bn_minlength Digits -> Fixnum.
21       // Genau bn_minlength Digits -> Bignum oder Fixnum.
22       if (len < bn_minlength)
23         { // 0..bn_minlength-1 Digits, paßt in ein Fixnum:
24           if (bn_minlength>1 ? (len==0) : TRUE)
25             // 0 Digits
26             { return 0; }
27           #if (cl_word_size <= 32)
28           var sint32 wert;
29           if (bn_minlength>2 ? (len==1) : TRUE)
30             // 1 Digit
31             len_1:
32             { wert = get_sint1D_Dptr(MSDptr mspop 1); }
33           elif (bn_minlength>3 ? (len==2) : TRUE)
34             // 2 Digits
35             len_2:
36             { wert = get_sint2D_Dptr(MSDptr mspop 2); }
37           elif (bn_minlength>4 ? (len==3) : TRUE)
38             // 3 Digits
39             len_3:
40             { wert = get_sint3D_Dptr(MSDptr mspop 3); }
41           elif (TRUE)
42             // 4 Digits
43             len_4:
44             { wert = get_sint4D_Dptr(MSDptr mspop 4); }
45           elif (FALSE)
46             // 5 Digits
47             len_5:
48             { wert = get_sint4D_Dptr(MSDptr mspop 5); }
49           return L_to_FN(wert);
50           #else // (cl_word_size==64)
51           var sint64 wert;
52           #if (intDsize==32)
53           if (TRUE)
54             // 1 Digit
55             len_1:
56             { wert = (sint64)(sintD)mspref(MSDptr,0); }
57           elif (FALSE)
58             // 2 Digits
59             len_2:
60             { wert = ((sint64)(sintD)mspref(MSDptr,0) << intDsize) | (uint64)(uintD)mspref(MSDptr,1); }
61           #endif
62           #if (intDsize==64)
63           if (FALSE)
64             // 1 Digit
65             len_1:
66             { wert = (sintD)mspref(MSDptr,0); }
67           #endif
68           return cl_I_from_word(cl_combine(cl_FN_tag,wert));
69           #endif
70         }
71       #if (cl_value_len > (bn_minlength-1)*intDsize)
72       if (len == bn_minlength)
73         // bn_minlength Digits, also (incl. Vorzeichen) zwischen
74         // (bn_minlength-1)*intDsize+1 und bn_minlength*intDsize Bits.
75         // Höchstens cl_value_len Bits -> paßt in ein Fixnum:
76         { if (  (mspref(MSDptr,0) <= (uintD)(bit(cl_value_len-1-(bn_minlength-1)*intDsize)-1)) // Fixnum >=0 ?
77               ||(mspref(MSDptr,0) >= (uintD)(-bit(cl_value_len-1-(bn_minlength-1)*intDsize))) // Fixnum <0 ?
78              )
79             #if (bn_minlength==1)
80             goto len_1;
81             #endif
82             #if (bn_minlength==2)
83             goto len_2;
84             #endif
85             #if (bn_minlength==3)
86             goto len_3;
87             #endif
88             #if (bn_minlength==4)
89             goto len_4;
90             #endif
91             #if (bn_minlength==5)
92             goto len_5;
93             #endif
94         }
95       #endif
96       // mindestens bn_minlength Digits, mache ein Bignum
97       { var Bignum result = allocate_bignum(len);
98         // neues Bignum mit dem Inhalt der NDS füllen:
99         copy_loop_msp(MSDptr,arrayMSDptr(result->data,len),len);
100         return result;
101       }
102 }
103
104 }  // namespace cln