]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_to_UL.cc
7ee081deeef4374d44b5657316999e3d680b9d50
[cln.git] / src / integer / conv / cl_I_to_UL.cc
1 // cl_I_to_UL().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cln/integer.h"
8
9
10 // Implementation.
11
12 #include "cln/number.h"
13 #include "cl_I.h"
14 #include "cl_DS.h"
15 #include "cln/io.h"
16 #include "cln/integer_io.h"
17 #include "cln/exception.h"
18 #include <sstream>
19
20 namespace cln {
21
22 uint32 cl_I_to_UL (const cl_I& obj)
23 {
24         if (fixnump(obj)) {
25                 // Fixnum
26                 var sintV wert = FN_to_V(obj);
27                 if (wert >= 0)
28                         #if (intVsize>32)
29                         if (wert < bit(32))
30                         #endif
31                                 return (uint32)wert;
32                 goto bad;
33         } else { // Bignum
34                 var cl_heap_bignum* bn = TheBignum(obj);
35                 var uintC len = bn->length;
36                 if ((sintD)mspref(arrayMSDptr(bn->data,len),0) < 0)
37                         goto bad;
38                 #define IF_LENGTH(i)  \
39                   if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
40                     if (len == i) /* genau i Digits? */                         \
41                       /* 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) */      \
42                       if ( (i*intDsize-1 > 32)                                  \
43                            && ( ((i-1)*intDsize-1 >= 32)                        \
44                                 || (mspref(arrayMSDptr(bn->data,len),0) >= (uintD)bitc(32-(i-1)*intDsize)) \
45                          )    )                                                 \
46                         goto bad;                                               \
47                         else
48                 IF_LENGTH(1)
49                         return get_uint1D_Dptr(arrayLSDptr(bn->data,1));
50                 IF_LENGTH(2)
51                         return get_uint2D_Dptr(arrayLSDptr(bn->data,2));
52                 IF_LENGTH(3)
53                         return get_uint3D_Dptr(arrayLSDptr(bn->data,3));
54                 IF_LENGTH(4)
55                         return get_uint4D_Dptr(arrayLSDptr(bn->data,4));
56                 IF_LENGTH(5)
57                         return get_uint4D_Dptr(arrayLSDptr(bn->data,5));
58                 #undef IF_LENGTH
59         }
60         bad: // unpassendes Objekt
61         std::ostringstream buf;
62         fprint(buf, "Not a 32-bit integer: ");
63         fprint(buf, obj);
64         throw runtime_exception(buf.str());
65 }
66
67 }  // namespace cln