]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_from_L.cc
* src/integer/conv/cl_I_to_digits (I_to_digits): Fix an elusive stack
[cln.git] / src / integer / conv / cl_I_from_L.cc
1 // L_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_value_len < 32)
15
16 #include "cl_DS.h"
17
18 namespace cln {
19
20 cl_private_thing cl_I_constructor_from_L (sint32 wert)
21 {
22         var uint32 test = wert & 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 == (uint32)minus_bit(cl_value_len-1)))
25                 { return (cl_private_thing)(cl_combine(cl_FN_tag,wert)); }
26         #if (intDsize==64)
27           // trivially generate a Bignum of length one digit
28           var cl_heap_bignum* ptr = allocate_bignum(1);
29           arrayLSref(ptr->data,1,0) = wert;
30           return (cl_private_thing)(ptr);
31         #else
32         // Bignum erzeugen:
33         // (dessen Länge  bn_minlength <= n <= ceiling(32/intDsize)  erfüllt)
34         if (bn_minlength == ceiling(32,intDsize)) {
35                 #if (intDsize==8)
36                 goto bignum4;
37                 #endif
38                 #if (intDsize==16)
39                 goto bignum2;
40                 #endif
41                 #if (intDsize==32)
42                 goto bignum1;
43                 #endif
44         }
45         if (wert >= 0) {
46                 #define IF_LENGTH(i)  \
47                   if ((bn_minlength <= i) && (i*intDsize <= 32))        \
48                     if (!((i+1)*intDsize <= 32)                         \
49                         || ((uint32)wert < (uint32)bitc(i*intDsize-1))  \
50                        )
51                 #if (intDsize <= 32)
52                 IF_LENGTH(1)
53                         bignum1:
54                         { var cl_heap_bignum* ptr = allocate_bignum(1);
55                           arrayLSref(ptr->data,1,0) = wert;
56                           return (cl_private_thing)(ptr);
57                         }
58                 #if (intDsize <= 16)
59                 IF_LENGTH(2)
60                         bignum2:
61                         { var cl_heap_bignum* ptr = allocate_bignum(2);
62                           arrayLSref(ptr->data,2,0) = (uintD)wert;
63                           arrayLSref(ptr->data,2,1) = (uintD)(wert>>intDsize);
64                           return (cl_private_thing)(ptr);
65                         }
66                 #if (intDsize <= 8)
67                 IF_LENGTH(3)
68                         bignum3:
69                         { var cl_heap_bignum* ptr = allocate_bignum(3);
70                           arrayLSref(ptr->data,3,0) = (uintD)wert; wert >>= intDsize;
71                           arrayLSref(ptr->data,3,1) = (uintD)wert;
72                           arrayLSref(ptr->data,3,2) = (uintD)(wert>>intDsize);
73                           return (cl_private_thing)(ptr);
74                         }
75                 IF_LENGTH(4)
76                         bignum4:
77                         { var cl_heap_bignum* ptr = allocate_bignum(4);
78                           arrayLSref(ptr->data,4,0) = (uintD)wert; wert >>= intDsize;
79                           arrayLSref(ptr->data,4,1) = (uintD)wert; wert >>= intDsize;
80                           arrayLSref(ptr->data,4,2) = (uintD)wert;
81                           arrayLSref(ptr->data,4,3) = (uintD)(wert>>intDsize);
82                           return (cl_private_thing)(ptr);
83                         }
84                 #endif
85                 #endif
86                 #endif
87                 #undef IF_LENGTH
88         } else {
89                 #define IF_LENGTH(i)  \
90                   if ((bn_minlength <= i) && (i*intDsize <= 32))        \
91                     if (!((i+1)*intDsize <= 32)                         \
92                         || ((uint32)wert >= (uint32)(-bitc(i*intDsize-1))) \
93                        )
94                 #if (intDsize <= 32)
95                 IF_LENGTH(1)
96                         goto bignum1;
97                 #if (intDsize <= 16)
98                 IF_LENGTH(2)
99                         goto bignum2;
100                 #if (intDsize <= 8)
101                 IF_LENGTH(3)
102                         goto bignum3;
103                 IF_LENGTH(4)
104                         goto bignum4;
105                 #endif
106                 #endif
107                 #endif
108                 #undef IF_LENGTH
109         }
110         #endif
111         NOTREACHED
112 }
113
114 }  // namespace cln
115
116 #endif