]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_from_UQ.cc
Fix integer input with leading zeros in power-of-two base.
[cln.git] / src / integer / conv / cl_I_from_UQ.cc
1 // UQ_to_I() helper.
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
14 #ifdef intQsize
15
16 #include "base/digitseq/cl_DS.h"
17
18 namespace cln {
19
20 cl_private_thing cl_I_constructor_from_UQ (uint64 wert)
21 {
22         if ((wert & (sint64)minus_bit(cl_value_len-1)) == 0)
23            // Bits, die nicht in den Fixnum-Wert >= 0 reinpassen.
24                 return (cl_private_thing)(cl_combine(cl_FN_tag,wert));
25         // Bignum erzeugen:
26         // (dessen Länge  bn_minlength <= n <= ceiling((32+1)/intDsize)  erfüllt)
27         #define UQ_maxlength  ceiling(64+1,intDsize)
28         #define IF_LENGTH(i)  \
29           if ((bn_minlength <= i) && (i <= UQ_maxlength))       \
30             if (!(i+1 <= UQ_maxlength)                          \
31                 || ((uint64)wert < ((uint64)1 << (i*intDsize-1 < 64 ? i*intDsize-1 : 0))) \
32                )
33         IF_LENGTH(1)
34                 { var cl_heap_bignum* ptr = allocate_bignum(1);
35                   arrayLSref(ptr->data,1,0) = (uintD)wert;
36                   return (cl_private_thing)(ptr);
37                 }
38         IF_LENGTH(2)
39                 { var cl_heap_bignum* ptr = allocate_bignum(2);
40                   arrayLSref(ptr->data,2,0) = (uintD)wert;
41                   #if (intDsize>=64)
42                   arrayLSref(ptr->data,2,1) = 0;
43                   #else
44                   arrayLSref(ptr->data,2,1) = (uintD)(wert>>intDsize);
45                   #endif
46                   return (cl_private_thing)(ptr);
47                 }
48         #if (intDsize <= 32)
49         IF_LENGTH(3)
50                 { var cl_heap_bignum* ptr = allocate_bignum(3);
51                   arrayLSref(ptr->data,3,0) = (uintD)wert; wert >>= intDsize;
52                   arrayLSref(ptr->data,3,1) = (uintD)wert;
53                   #if (2*intDsize>=64)
54                   arrayLSref(ptr->data,3,2) = 0;
55                   #else
56                   arrayLSref(ptr->data,3,2) = (uintD)(wert>>intDsize);
57                   #endif
58                   return (cl_private_thing)(ptr);
59                 }
60         #if (intDsize <= 16)
61         IF_LENGTH(4)
62                 { var cl_heap_bignum* ptr = allocate_bignum(4);
63                   arrayLSref(ptr->data,4,0) = (uintD)wert; wert >>= intDsize;
64                   arrayLSref(ptr->data,4,1) = (uintD)wert; wert >>= intDsize;
65                   arrayLSref(ptr->data,4,2) = (uintD)wert;
66                   #if (3*intDsize>=64)
67                   arrayLSref(ptr->data,4,3) = 0;
68                   #else
69                   arrayLSref(ptr->data,4,3) = (uintD)(wert>>intDsize);
70                   #endif
71                   return (cl_private_thing)(ptr);
72                 }
73         IF_LENGTH(5)
74                 { var cl_heap_bignum* ptr = allocate_bignum(5);
75                   arrayLSref(ptr->data,5,0) = (uintD)wert; wert >>= intDsize;
76                   arrayLSref(ptr->data,5,1) = (uintD)wert; wert >>= intDsize;
77                   arrayLSref(ptr->data,5,2) = (uintD)wert; wert >>= intDsize;
78                   arrayLSref(ptr->data,5,3) = (uintD)wert;
79                   #if (4*intDsize>=64)
80                   arrayLSref(ptr->data,5,4) = 0;
81                   #else
82                   arrayLSref(ptr->data,5,4) = (uintD)(wert>>intDsize);
83                   #endif
84                   return (cl_private_thing)(ptr);
85                 }
86         #if (intDsize <= 8)
87         IF_LENGTH(6)
88                 { var cl_heap_bignum* ptr = allocate_bignum(6);
89                   arrayLSref(ptr->data,6,0) = (uintD)wert; wert >>= intDsize;
90                   arrayLSref(ptr->data,6,1) = (uintD)wert; wert >>= intDsize;
91                   arrayLSref(ptr->data,6,2) = (uintD)wert; wert >>= intDsize;
92                   arrayLSref(ptr->data,6,3) = (uintD)wert; wert >>= intDsize;
93                   arrayLSref(ptr->data,6,4) = (uintD)wert;
94                   #if (5*intDsize>=64)
95                   arrayLSref(ptr->data,6,5) = 0;
96                   #else
97                   arrayLSref(ptr->data,6,5) = (uintD)(wert>>intDsize);
98                   #endif
99                   return (cl_private_thing)(ptr);
100                 }
101         IF_LENGTH(7)
102                 { var cl_heap_bignum* ptr = allocate_bignum(7);
103                   arrayLSref(ptr->data,7,0) = (uintD)wert; wert >>= intDsize;
104                   arrayLSref(ptr->data,7,1) = (uintD)wert; wert >>= intDsize;
105                   arrayLSref(ptr->data,7,2) = (uintD)wert; wert >>= intDsize;
106                   arrayLSref(ptr->data,7,3) = (uintD)wert; wert >>= intDsize;
107                   arrayLSref(ptr->data,7,4) = (uintD)wert; wert >>= intDsize;
108                   arrayLSref(ptr->data,7,5) = (uintD)wert;
109                   #if (6*intDsize>=64)
110                   arrayLSref(ptr->data,7,6) = 0;
111                   #else
112                   arrayLSref(ptr->data,7,6) = (uintD)(wert>>intDsize);
113                   #endif
114                   return (cl_private_thing)(ptr);
115                 }
116         IF_LENGTH(8)
117                 { var cl_heap_bignum* ptr = allocate_bignum(8);
118                   arrayLSref(ptr->data,8,0) = (uintD)wert; wert >>= intDsize;
119                   arrayLSref(ptr->data,8,1) = (uintD)wert; wert >>= intDsize;
120                   arrayLSref(ptr->data,8,2) = (uintD)wert; wert >>= intDsize;
121                   arrayLSref(ptr->data,8,3) = (uintD)wert; wert >>= intDsize;
122                   arrayLSref(ptr->data,8,4) = (uintD)wert; wert >>= intDsize;
123                   arrayLSref(ptr->data,8,5) = (uintD)wert; wert >>= intDsize;
124                   arrayLSref(ptr->data,8,6) = (uintD)wert;
125                   #if (7*intDsize>=64)
126                   arrayLSref(ptr->data,8,7) = 0;
127                   #else
128                   arrayLSref(ptr->data,8,7) = (uintD)(wert>>intDsize);
129                   #endif
130                   return (cl_private_thing)(ptr);
131                 }
132         IF_LENGTH(9)
133                 { var cl_heap_bignum* ptr = allocate_bignum(9);
134                   arrayLSref(ptr->data,9,0) = (uintD)wert; wert >>= intDsize;
135                   arrayLSref(ptr->data,9,1) = (uintD)wert; wert >>= intDsize;
136                   arrayLSref(ptr->data,9,2) = (uintD)wert; wert >>= intDsize;
137                   arrayLSref(ptr->data,9,3) = (uintD)wert; wert >>= intDsize;
138                   arrayLSref(ptr->data,9,4) = (uintD)wert; wert >>= intDsize;
139                   arrayLSref(ptr->data,9,5) = (uintD)wert; wert >>= intDsize;
140                   arrayLSref(ptr->data,9,6) = (uintD)wert; wert >>= intDsize;
141                   arrayLSref(ptr->data,9,7) = (uintD)wert;
142                   #if (8*intDsize>=64)
143                   arrayLSref(ptr->data,9,8) = 0;
144                   #else
145                   arrayLSref(ptr->data,9,8) = (uintD)(wert>>intDsize);
146                   #endif
147                   return (cl_private_thing)(ptr);
148                 }
149         #endif
150         #endif
151         #endif
152         #undef IF_LENGTH
153         #undef UQ_maxlength
154 }
155
156 }  // namespace cln
157
158 #endif