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