// cl_I_to_Q().
// General includes.
#include "cl_sysdep.h"
// Specification.
#include "cl_I.h"
// Implementation.
#ifdef intQsize
#include "cln/number.h"
#include "cl_DS.h"
#include "cln/io.h"
#include "cln/integer_io.h"
#include "cln/abort.h"
namespace cln {
sint64 cl_I_to_Q (const cl_I& obj)
{
if (fixnump(obj))
// Fixnum
return (sint64)(sint32)FN_to_L(obj);
{ // Bignum
var cl_heap_bignum* bn = TheBignum(obj);
var uintC len = bn->length;
if ((sintD)mspref(arrayMSDptr(bn->data,len),0) >= 0) {
// Bignum > 0
#define IF_LENGTH(i) \
if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
if (len == i) /* genau i Digits? */ \
/* 2^((i-1)*intDsize-1) <= obj < 2^(i*intDsize-1) */ \
if ( (i*intDsize > 64) \
&& ( ((i-1)*intDsize >= 64) \
|| (mspref(arrayMSDptr(bn->data,len),0) >= (uintD)bitc(63-(i-1)*intDsize)) \
) ) \
goto bad; \
else
#if (intDsize==64)
IF_LENGTH(1)
return (uint64)arrayLSref(bn->data,1,0);
#endif
#if (intDsize==32)
IF_LENGTH(1)
return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
IF_LENGTH(2)
return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,2) lspop 1) << 32) | (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,2));
#endif
#if (intDsize==16)
IF_LENGTH(1)
return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
IF_LENGTH(2)
return (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,2));
IF_LENGTH(3)
return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,3) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,3));
IF_LENGTH(4)
return ((uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,4) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,4));
#endif
#if (intDsize==8)
IF_LENGTH(1)
return (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,1));
IF_LENGTH(2)
return (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,2));
IF_LENGTH(3)
return (uint64)get_uint3D_Dptr(arrayLSDptr(bn->data,3));
IF_LENGTH(4)
return (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,4));
IF_LENGTH(5)
return ((uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,5) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,5));
IF_LENGTH(6)
return ((uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,6) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,6));
IF_LENGTH(7)
return ((uint64)get_uint3D_Dptr(arrayLSDptr(bn->data,7) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,7));
IF_LENGTH(8)
return ((uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,8) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,8));
#endif
#undef IF_LENGTH
} else {
// Bignum < 0
#define IF_LENGTH(i) \
if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
if (len == i) /* genau i Digits? */ \
/* - 2^(i*intDsize-1) <= obj < - 2^((i-1)*intDsize-1) */ \
if ( (i*intDsize > 64) \
&& ( ((i-1)*intDsize >= 64) \
|| (mspref(arrayMSDptr(bn->data,len),0) < (uintD)(-bitc(63-(i-1)*intDsize))) \
) ) \
goto bad; \
else
#if (intDsize==64)
IF_LENGTH(1)
return (sint64)arrayLSref(bn->data,1,0);
#endif
#if (intDsize==32)
IF_LENGTH(1)
return (sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,1));
IF_LENGTH(2)
return ((sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,2) lspop 1) << 32) | (uint64)get_uint1D_Dptr(arrayLSDptr(bn->data,2));
#endif
#if (intDsize==16)
IF_LENGTH(1)
return (sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,1));
IF_LENGTH(2)
return (sint64)get_sint2D_Dptr(arrayLSDptr(bn->data,2));
IF_LENGTH(3)
return ((sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,3) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,3));
IF_LENGTH(4)
return ((sint64)get_sint2D_Dptr(arrayLSDptr(bn->data,4) lspop 2) << 32) | (uint64)get_uint2D_Dptr(arrayLSDptr(bn->data,4));
#endif
#if (intDsize==8)
IF_LENGTH(1)
return (sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,1));
IF_LENGTH(2)
return (sint64)get_sint2D_Dptr(arrayLSDptr(bn->data,2));
IF_LENGTH(3)
return (sint64)get_sint3D_Dptr(arrayLSDptr(bn->data,3));
IF_LENGTH(4)
return (sint64)get_sint4D_Dptr(arrayLSDptr(bn->data,4));
IF_LENGTH(5)
return ((sint64)get_sint1D_Dptr(arrayLSDptr(bn->data,5) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,5));
IF_LENGTH(6)
return ((sint64)get_sint2D_Dptr(arrayLSDptr(bn->data,6) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,6));
IF_LENGTH(7)
return ((sint64)get_sint3D_Dptr(arrayLSDptr(bn->data,7) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,7));
IF_LENGTH(8)
return ((sint64)get_sint4D_Dptr(arrayLSDptr(bn->data,8) lspop 4) << 32) | (uint64)get_uint4D_Dptr(arrayLSDptr(bn->data,8));
#endif
#undef IF_LENGTH
}
bad: // unpassendes Objekt
fprint(std::cerr, "Not a 64-bit integer: ");
fprint(std::cerr, obj);
fprint(std::cerr, "\n");
cl_abort();
}
}
} // namespace cln
#endif
syntax highlighted by Code2HTML, v. 0.9.1