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