]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_to_L.cc
* */*: Removed problematic stdin, stdout and stderr definitions.
[cln.git] / src / integer / conv / cl_I_to_L.cc
1 // cl_I_to_L().
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/abort.h"
18
19 namespace cln {
20
21 sint32 cl_I_to_L (const cl_I& obj)
22 {
23         if (fixnump(obj))
24                 // Fixnum
25                 return FN_to_L(obj);
26     {   // Bignum
27         var cl_heap_bignum* bn = TheBignum(obj);
28         var uintC len = bn->length;
29         if ((sintD)mspref(arrayMSDptr(bn->data,len),0) >= 0) {
30                 // Bignum > 0
31                 #define IF_LENGTH(i)  \
32                   if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
33                     if (len == i) /* genau i Digits? */                         \
34                       /* 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) */      \
35                       if ( (i*intDsize > 32)                                    \
36                            && ( ((i-1)*intDsize >= 32)                          \
37                                 || (mspref(arrayMSDptr(bn->data,len),0) >= (uintD)bitc(31-(i-1)*intDsize)) \
38                          )    )                                                 \
39                         goto bad;                                               \
40                         else
41                 IF_LENGTH(1)
42                         return get_uint1D_Dptr(arrayLSDptr(bn->data,1));
43                 IF_LENGTH(2)
44                         return get_uint2D_Dptr(arrayLSDptr(bn->data,2));
45                 IF_LENGTH(3)
46                         return get_uint3D_Dptr(arrayLSDptr(bn->data,3));
47                 IF_LENGTH(4)
48                         return get_uint4D_Dptr(arrayLSDptr(bn->data,4));
49                 #undef IF_LENGTH
50         } else {
51                 // Bignum < 0
52                 #define IF_LENGTH(i)  \
53                   if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
54                     if (len == i) /* genau i Digits? */                         \
55                       /* - 2^(i*intDsize-1) <= obj < - 2^((i-1)*intDsize-1) */  \
56                       if ( (i*intDsize > 32)                                    \
57                            && ( ((i-1)*intDsize >= 32)                          \
58                                 || (mspref(arrayMSDptr(bn->data,len),0) < (uintD)(-bitc(31-(i-1)*intDsize))) \
59                          )    )                                                 \
60                         goto bad;                                               \
61                         else
62                 IF_LENGTH(1)
63                         return get_sint1D_Dptr(arrayLSDptr(bn->data,1));
64                 IF_LENGTH(2)
65                         return get_sint2D_Dptr(arrayLSDptr(bn->data,2));
66                 IF_LENGTH(3)
67                         return get_sint3D_Dptr(arrayLSDptr(bn->data,3));
68                 IF_LENGTH(4)
69                         return get_sint4D_Dptr(arrayLSDptr(bn->data,4));
70                 #undef IF_LENGTH
71         }
72         bad: // unpassendes Objekt
73         fprint(std::cerr, "Not a 32-bit integer: ");
74         fprint(std::cerr, obj);
75         fprint(std::cerr, "\n");
76         cl_abort();
77     }
78 }
79
80 }  // namespace cln