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