]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_to_L.cc
Replace unused macro with cl_unused.
[cln.git] / src / integer / conv / cl_I_to_L.cc
1 // cl_I_to_L().
2
3 // General includes.
4 #include "base/cl_sysdep.h"
5
6 // Specification.
7 #include "cln/integer.h"
8
9
10 // Implementation.
11
12 #include "cln/number.h"
13 #include "integer/cl_I.h"
14 #include "base/digitseq/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 sint32 cl_I_to_L (const cl_I& obj)
23 {
24         if (fixnump(obj)) {
25                 // Fixnum
26                 var sintV wert = FN_to_V(obj);
27                 #if (intVsize>32)
28                 if ((sintV)(sint32)wert != wert)
29                         goto bad;
30                 #endif
31                 return (sint32)wert;
32         } else { // Bignum
33                 var cl_heap_bignum* bn = TheBignum(obj);
34                 var uintC len = bn->length;
35                 if ((sintD)mspref(arrayMSDptr(bn->data,len),0) >= 0) {
36                         // Bignum > 0
37                         #define IF_LENGTH(i)  \
38                           if ((bn_minlength <= i) /* genau i Digits überhaupt möglich? */     \
39                             && (len == i) /* genau i Digits? */                                 \
40                             /* 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) */                \
41                             && ( (i*intDsize > 32)                                              \
42                                  && ( ((i-1)*intDsize >= 32)                                    \
43                                       || (mspref(arrayMSDptr(bn->data,len),0) >= (uintD)bitc(31-(i-1)*intDsize)) \
44                              ) )    )                                                           \
45                             goto bad;                                                           \
46                             else
47                         IF_LENGTH(1)
48                                 return get_uint1D_Dptr(arrayLSDptr(bn->data,1));
49                         IF_LENGTH(2)
50                                 return get_uint2D_Dptr(arrayLSDptr(bn->data,2));
51                         IF_LENGTH(3)
52                                 return get_uint3D_Dptr(arrayLSDptr(bn->data,3));
53                         IF_LENGTH(4)
54                                 return get_uint4D_Dptr(arrayLSDptr(bn->data,4));
55                         #undef IF_LENGTH
56                 } else {
57                         // Bignum < 0
58                         #define IF_LENGTH(i)  \
59                           if ((bn_minlength <= i) /* genau i Digits überhaupt möglich? */     \
60                             && (len == i) /* genau i Digits? */                                 \
61                             /* - 2^(i*intDsize-1) <= obj < - 2^((i-1)*intDsize-1) */            \
62                             && ( (i*intDsize > 32)                                              \
63                                  && ( ((i-1)*intDsize >= 32)                                    \
64                                       || (mspref(arrayMSDptr(bn->data,len),0) < (uintD)(-bitc(31-(i-1)*intDsize))) \
65                              ) )    )                                                           \
66                             goto bad;                                                           \
67                             else
68                         IF_LENGTH(1)
69                                 return get_sint1D_Dptr(arrayLSDptr(bn->data,1));
70                         IF_LENGTH(2)
71                                 return get_sint2D_Dptr(arrayLSDptr(bn->data,2));
72                         IF_LENGTH(3)
73                                 return get_sint3D_Dptr(arrayLSDptr(bn->data,3));
74                         IF_LENGTH(4)
75                                 return get_sint4D_Dptr(arrayLSDptr(bn->data,4));
76                         #undef IF_LENGTH
77                 }
78         }
79         bad: // unpassendes Objekt
80         std::ostringstream buf;
81         fprint(buf, "Not a 32-bit integer: ");
82         fprint(buf, obj);
83         throw runtime_exception(buf.str());
84 }
85
86 }  // namespace cln