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