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