]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_to_UQ.cc
Remove exception hooks in favor of real C++ exceptions:
[cln.git] / src / integer / conv / cl_I_to_UQ.cc
1 // cl_I_to_UQ().
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/exception.h"
19 #include <sstream>
20
21 namespace cln {
22
23 uint64 cl_I_to_UQ (const cl_I& obj)
24 {
25         if (fixnump(obj)) {
26                 // Fixnum
27                 var sintV wert = FN_to_V(obj);
28                 if (wert >= 0)
29                         return (uint64)(uintV)wert;
30                 goto bad;
31         } else { // Bignum
32                 var cl_heap_bignum* bn = TheBignum(obj);
33                 var uintC len = bn->length;
34                 if ((sintD)mspref(arrayMSDptr(bn->data,len),0) < 0)
35                         goto bad;
36                 #define IF_LENGTH(i)  \
37                   if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
38                     if (len == i) /* genau i Digits? */                         \
39                       /* 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) */      \
40                       if ( (i*intDsize-1 > 64)                                  \
41                            && ( ((i-1)*intDsize-1 >= 64)                        \
42                                 || (mspref(arrayMSDptr(bn->data,len),0) >= (uintD)bitc(64-(i-1)*intDsize)) \
43                          )    )                                                 \
44                         goto bad;                                               \
45                         else
46                 #if (intDsize==64)
47                 IF_LENGTH(1)
48                         return (uint64)arrayLSref(bn->data,1,0);
49                 IF_LENGTH(2)
50                         return (uint64)arrayLSref(bn->data,2,0);
51                 #endif
52                 #if (intDsize==32)
53                 IF_LENGTH(1)
54                         return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
55                 IF_LENGTH(2)
56                         return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,2) lspop 1) << 32) | (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,2));
57                 IF_LENGTH(3)
58                         return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,3) lspop 1) << 32) | (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,3));
59                 #endif
60                 #if (intDsize==16)
61                 IF_LENGTH(1)
62                         return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
63                 IF_LENGTH(2)
64                         return (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,2));
65                 IF_LENGTH(3)
66                         return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,3) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,3));
67                 IF_LENGTH(4)
68                         return ((uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,4) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,4));
69                 IF_LENGTH(5)
70                         return ((uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,5) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,5));
71                 #endif
72                 #if (intDsize==8)
73                 IF_LENGTH(1)
74                         return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
75                 IF_LENGTH(2)
76                         return (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,2));
77                 IF_LENGTH(3)
78                         return (uint64)get_uint3D_Dptr(arrayLSDptr(bn->data,3));
79                 IF_LENGTH(4)
80                         return (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,4));
81                 IF_LENGTH(5)
82                         return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,5) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,5));
83                 IF_LENGTH(6)
84                         return ((uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,6) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,6));
85                 IF_LENGTH(7)
86                         return ((uint64)get_uint3D_Dptr(arrayLSDptr(bn->data,7) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,7));
87                 IF_LENGTH(8)
88                         return ((uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,8) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,8));
89                 IF_LENGTH(9)
90                         return ((uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,9) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,9));
91                 #endif
92                 #undef IF_LENGTH
93         }
94         bad: // unpassendes Objekt
95         std::ostringstream buf;
96         fprint(buf, "Not a 64-bit integer: ");
97         fprint(buf, obj);
98         throw runtime_exception(buf.str());
99 }
100
101 }  // namespace cln
102
103 #endif