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