]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_from_L2.cc
Initial revision
[cln.git] / src / integer / conv / cl_I_from_L2.cc
1 // L2_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 #include "cl_DS.h"
14
15 cl_private_thing cl_I_constructor_from_L2 (sint32 wert_hi, uint32 wert_lo)
16 {
17         if (wert_hi == 0) {
18                 if ((wert_lo & minus_bit(cl_value_len-1)) == 0)
19                         return (cl_private_thing)(cl_combine(cl_FN_tag,wert_lo));
20         }
21         elif (wert_hi == ~(sint32)0) {
22                 if ((~wert_lo & minus_bit(cl_value_len-1)) == 0)
23                         return (cl_private_thing)(cl_combine(cl_FN_tag,(sint32)wert_lo));
24         }
25         // Bignum erzeugen:
26         // (dessen Länge  bn_minlength <= n <= ceiling(64/intDsize)  erfüllt)
27         #define FILL_1_DIGIT(l,i,from) \
28                 arrayLSref(ptr->data,l,i) = (uintD)from;
29         #define FILL_2_DIGIT(l,i,from) \
30                 arrayLSref(ptr->data,l,i) = (uintD)from; \
31                 arrayLSref(ptr->data,l,i+1) = (uintD)(from>>intDsize);
32         #define FILL_3_DIGIT(l,i,from) \
33                 arrayLSref(ptr->data,l,i) = (uintD)from; from>>=intDsize; \
34                 arrayLSref(ptr->data,l,i+1) = (uintD)from; \
35                 arrayLSref(ptr->data,l,i+2) = (uintD)(from>>intDsize);
36         #define FILL_4_DIGIT(l,i,from) \
37                 arrayLSref(ptr->data,l,i) = (uintD)from; from>>=intDsize; \
38                 arrayLSref(ptr->data,l,i+1) = (uintD)from; from>>=intDsize; \
39                 arrayLSref(ptr->data,l,i+2) = (uintD)from; \
40                 arrayLSref(ptr->data,l,i+3) = (uintD)(from>>intDsize);
41         #if (intDsize==64)
42         #define FILL_1  FILL_1_DIGIT(1,0,highlow64(wert_hi,wert_lo));
43         #endif
44         #if (32/intDsize==1)
45         #define FILL_1  FILL_1_DIGIT(1,0,wert_lo);
46         #define FILL_2  FILL_1_DIGIT(2,1,wert_hi); FILL_1_DIGIT(2,0,wert_lo);
47         #endif
48         #if (32/intDsize==2)
49         #define FILL_1  FILL_1_DIGIT(1,0,wert_lo);
50         #define FILL_2  FILL_2_DIGIT(2,0,wert_lo);
51         #define FILL_3  FILL_1_DIGIT(3,2,wert_hi); FILL_2_DIGIT(3,0,wert_lo);
52         #define FILL_4  FILL_2_DIGIT(4,2,wert_hi); FILL_2_DIGIT(4,0,wert_lo);
53         #endif
54         #if (32/intDsize==4)
55         #define FILL_1  FILL_1_DIGIT(1,0,wert_lo);
56         #define FILL_2  FILL_2_DIGIT(2,0,wert_lo);
57         #define FILL_3  FILL_3_DIGIT(3,0,wert_lo);
58         #define FILL_4  FILL_4_DIGIT(4,0,wert_lo);
59         #define FILL_5  FILL_1_DIGIT(5,4,wert_hi); FILL_4_DIGIT(5,0,wert_lo);
60         #define FILL_6  FILL_2_DIGIT(6,4,wert_hi); FILL_4_DIGIT(6,0,wert_lo);
61         #define FILL_7  FILL_3_DIGIT(7,4,wert_hi); FILL_4_DIGIT(7,0,wert_lo);
62         #define FILL_8  FILL_4_DIGIT(8,4,wert_hi); FILL_4_DIGIT(8,0,wert_lo);
63         #endif
64         if (wert_hi >= 0) {
65                 #define IF_LENGTH(i)  \
66                   if ((bn_minlength <= i) && (i*intDsize <= 64))        \
67                     if (!((i+1)*intDsize <= 64)                         \
68                         || (i*intDsize-1 < 32                           \
69                             ? ((wert_hi == 0) && (wert_lo < (uint32)bitc(i*intDsize-1))) \
70                             : ((uint32)wert_hi < (uint32)bitc(i*intDsize-1-32)) \
71                        )   )
72                 #define ALLOC(i)  \
73                   var cl_heap_bignum* ptr = allocate_bignum(i);
74                 #define OK  \
75                   return (cl_private_thing)(ptr);
76                 IF_LENGTH(1)
77                         bignum1: { ALLOC(1); FILL_1; OK; }
78                 #if (intDsize <= 32)
79                 IF_LENGTH(2)
80                         bignum2: { ALLOC(2); FILL_2; OK; }
81                 #if (intDsize <= 16)
82                 IF_LENGTH(3)
83                         bignum3: { ALLOC(3); FILL_3; OK; }
84                 IF_LENGTH(4)
85                         bignum4: { ALLOC(4); FILL_4; OK; }
86                 #if (intDsize <= 8)
87                 IF_LENGTH(5)
88                         bignum5: { ALLOC(5); FILL_5; OK; }
89                 IF_LENGTH(6)
90                         bignum6: { ALLOC(6); FILL_6; OK; }
91                 IF_LENGTH(7)
92                         bignum7: { ALLOC(7); FILL_7; OK; }
93                 IF_LENGTH(8)
94                         bignum8: { ALLOC(8); FILL_8; OK; }
95                 #endif
96                 #endif
97                 #endif
98                 #undef IF_LENGTH
99         } else {
100                 #define IF_LENGTH(i)  \
101                   if ((bn_minlength <= i) && (i*intDsize <= 64))        \
102                     if (!((i+1)*intDsize <= 64)                         \
103                         || (i*intDsize-1 < 32                           \
104                             ? ((wert_hi == ~(sint32)0) && (wert_lo >= (uint32)(-bitc(i*intDsize-1)))) \
105                             : ((uint32)wert_hi >= (uint32)(-bitc(i*intDsize-1-32))) \
106                        )   )
107                 IF_LENGTH(1)
108                         goto bignum1;
109                 #if (intDsize <= 32)
110                 IF_LENGTH(2)
111                         goto bignum2;
112                 #if (intDsize <= 16)
113                 IF_LENGTH(3)
114                         goto bignum3;
115                 IF_LENGTH(4)
116                         goto bignum4;
117                 #if (intDsize <= 8)
118                 IF_LENGTH(5)
119                         goto bignum5;
120                 IF_LENGTH(6)
121                         goto bignum6;
122                 IF_LENGTH(7)
123                         goto bignum7;
124                 IF_LENGTH(8)
125                         goto bignum8;
126                 #endif
127                 #endif
128                 #endif
129                 #undef IF_LENGTH
130         }
131 }