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