]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_to_Q.cc
Extend the exponent range from 32 bits to 64 bits on selected platforms.
[cln.git] / src / integer / conv / cl_I_to_Q.cc
1 // cl_I_to_Q().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_I.h"
8
9
10 // Implementation.
11
12 #ifdef intQsize
13
14 #include "cln/number.h"
15 #include "cl_DS.h"
16 #include "cln/io.h"
17 #include "cln/integer_io.h"
18 #include "cln/abort.h"
19
20 namespace cln {
21
22 sint64 cl_I_to_Q (const cl_I& obj)
23 {
24         if (fixnump(obj))
25                 // Fixnum
26                 return (sint64)(sintV)FN_to_V(obj);
27     {   // Bignum
28         var cl_heap_bignum* bn = TheBignum(obj);
29         var uintC len = bn->length;
30         if ((sintD)mspref(arrayMSDptr(bn->data,len),0) >= 0) {
31                 // Bignum > 0
32                 #define IF_LENGTH(i)  \
33                   if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
34                     if (len == i) /* genau i Digits? */                         \
35                       /* 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) */      \
36                       if ( (i*intDsize > 64)                                    \
37                            && ( ((i-1)*intDsize >= 64)                          \
38                                 || (mspref(arrayMSDptr(bn->data,len),0) >= (uintD)bitc(63-(i-1)*intDsize)) \
39                          )    )                                                 \
40                         goto bad;                                               \
41                         else
42                 #if (intDsize==64)
43                 IF_LENGTH(1)
44                         return (uint64)arrayLSref(bn->data,1,0);
45                 #endif
46                 #if (intDsize==32)
47                 IF_LENGTH(1)
48                         return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
49                 IF_LENGTH(2)
50                         return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,2) lspop 1) << 32) | (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,2));
51                 #endif
52                 #if (intDsize==16)
53                 IF_LENGTH(1)
54                         return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
55                 IF_LENGTH(2)
56                         return (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,2));
57                 IF_LENGTH(3)
58                         return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,3) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,3));
59                 IF_LENGTH(4)
60                         return ((uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,4) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,4));
61                 #endif
62                 #if (intDsize==8)
63                 IF_LENGTH(1)
64                         return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
65                 IF_LENGTH(2)
66                         return (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,2));
67                 IF_LENGTH(3)
68                         return (uint64)get_uint3D_Dptr(arrayLSDptr(bn->data,3));
69                 IF_LENGTH(4)
70                         return (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,4));
71                 IF_LENGTH(5)
72                         return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,5) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,5));
73                 IF_LENGTH(6)
74                         return ((uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,6) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,6));
75                 IF_LENGTH(7)
76                         return ((uint64)get_uint3D_Dptr(arrayLSDptr(bn->data,7) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,7));
77                 IF_LENGTH(8)
78                         return ((uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,8) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,8));
79                 #endif
80                 #undef IF_LENGTH
81         } else {
82                 // Bignum < 0
83                 #define IF_LENGTH(i)  \
84                   if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
85                     if (len == i) /* genau i Digits? */                         \
86                       /* - 2^(i*intDsize-1) <= obj < - 2^((i-1)*intDsize-1) */  \
87                       if ( (i*intDsize > 64)                                    \
88                            && ( ((i-1)*intDsize >= 64)                          \
89                                 || (mspref(arrayMSDptr(bn->data,len),0) < (uintD)(-bitc(63-(i-1)*intDsize))) \
90                          )    )                                                 \
91                         goto bad;                                               \
92                         else
93                 #if (intDsize==64)
94                 IF_LENGTH(1)
95                         return (sint64)arrayLSref(bn->data,1,0);
96                 #endif
97                 #if (intDsize==32)
98                 IF_LENGTH(1)
99                         return (sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,1));
100                 IF_LENGTH(2)
101                         return ((sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,2) lspop 1) << 32) | (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,2));
102                 #endif
103                 #if (intDsize==16)
104                 IF_LENGTH(1)
105                         return (sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,1));
106                 IF_LENGTH(2)
107                         return (sint64)get_sint2D_Dptr(arrayLSDptr(bn->data,2));
108                 IF_LENGTH(3)
109                         return ((sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,3) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,3));
110                 IF_LENGTH(4)
111                         return ((sint64)get_sint2D_Dptr(arrayLSDptr(bn->data,4) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,4));
112                 #endif
113                 #if (intDsize==8)
114                 IF_LENGTH(1)
115                         return (sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,1));
116                 IF_LENGTH(2)
117                         return (sint64)get_sint2D_Dptr(arrayLSDptr(bn->data,2));
118                 IF_LENGTH(3)
119                         return (sint64)get_sint3D_Dptr(arrayLSDptr(bn->data,3));
120                 IF_LENGTH(4)
121                         return (sint64)get_sint4D_Dptr(arrayLSDptr(bn->data,4));
122                 IF_LENGTH(5)
123                         return ((sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,5) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,5));
124                 IF_LENGTH(6)
125                         return ((sint64)get_sint2D_Dptr(arrayLSDptr(bn->data,6) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,6));
126                 IF_LENGTH(7)
127                         return ((sint64)get_sint3D_Dptr(arrayLSDptr(bn->data,7) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,7));
128                 IF_LENGTH(8)
129                         return ((sint64)get_sint4D_Dptr(arrayLSDptr(bn->data,8) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,8));
130                 #endif
131                 #undef IF_LENGTH
132         }
133         bad: // unpassendes Objekt
134         fprint(std::cerr, "Not a 64-bit integer: ");
135         fprint(std::cerr, obj);
136         fprint(std::cerr, "\n");
137         cl_abort();
138     }
139 }
140
141 }  // namespace cln
142
143 #endif