1 #ifndef CONVERTER_INT_H
2 #define CONVERTER_INT_H
11 //#elif defined( defined(SCOPLIB_INT_T_IS_MP)
15 #include "osl/macros.h"
16 #include "converter/converter.h"
18 #ifdef OSL_GMP_IS_HERE
20 * Function to check if mpz_t fits inside a long long int
22 * \param[in] x mpz_t to check
23 * \return 1 if yes, 0 other wise
24 * http://cpansearch.perl.org/src/BUBAFLUB/Math-Primality-0.04/spec/bpsw/trn.c
27 int convert_mpz_fits_llong_p(mpz_t x
){
31 CONVERTER_malloc(szULL
, char *, 2 + ceil(log10(LLONG_MAX
)));
32 mpz_init2(llMax
, floor(0.5 + log10(LLONG_MAX
)/log10(2)));
33 sprintf(szULL
, "%lld", LLONG_MAX
);
34 mpz_set_str(llMax
, szULL
, 10);
35 //(mpz_sgn(x) >= 0) &&
36 if( (mpz_cmp(x
, llMax
) > 0)){
40 else { // what about LLONG_MIN??
48 * Function to convert an mpz into a long long int
50 * \param[in] x mpz_t to convert
51 * \return converted long long int
54 long long int convert_mpz_get_lld(mpz_t x
){
57 CONVERTER_malloc(szLLD
, char *, 2 + ceil(log10(LLONG_MAX
)));
59 mpz_get_str(szLLD
, 10, x
);
60 unsigned long long lld
=strtoll(szLLD
, NULL
, 10);
73 //http://cpansearch.perl.org/src/BUBAFLUB/Math-Primality-0.04/spec/bpsw/trn.c
74 // see also: http://www.velocityreviews.com/forums/t317412-limits-h-and-int-len.html
76 //mpz type declares an array of size 1; therefoer the name of the variable
78 //declaring a simple pointer necessitates allocation of the object explicitly;
79 //while declaring an array of size one creates the objects statically and lets
80 //use the variable name as a pointer at the same time!
83 * Function to assign a long long it to an mpz_t
85 * \param[in] x mpz_t to convert
86 * \return converted long long int
89 void convert_mpz_set_lld(mpz_t mpz
, long long int x
){
92 //(char *)malloc(3 + (sizeof(unsigned long long)*CHAR_BIT*3)/10);
93 //(char *)malloc(sizeof (long long int) * CHAR_BIT * 8 / 25 + 3);
94 CONVERTER_malloc(szULL
, char *, sizeof (long long int) * CHAR_BIT
* 8 / 25 + 3);
95 sprintf(szULL
, "%lld", x
);
96 mpz_set_str(mpz
, szULL
, 10);
100 #endif //OSL_GMP_IS_HERE
104 * Function used in copying scoplib_matrix to a osl_relation.
105 * Assigns a value in scoplib_matrix, to an offset in osl_relation
108 * \param[in] dest_precision precision of the destination osl relation
109 * \param[in] dest address of the destination osl_int_t
110 * \param[in] src source scoplib_int_t to convert from
114 void convert_int_assign_scoplib2osl(int dest_precision
, osl_int_p dest
,
117 switch(dest_precision
){
118 case OSL_PRECISION_SP
:
119 #ifdef SCOPLIB_INT_T_IS_LONG
120 dest
->sp
= (long int)src
;
121 #elif defined( SCOPLIB_INT_T_IS_LONGLONG)
123 CONVERTER_error("Conversion of longlong into long. Loss of information");
125 dest
->sp
= (long int)src
; // loss of precision??
126 #elif defined( SCOPLIB_INT_T_IS_MP)
127 if( !mpz_fits_slong_p(src
))
128 CONVERTER_error("Conversion of MP-type into long. Loss of information");
130 dest
->sp
= mpz_get_si(src
); // loss of precision??
134 case OSL_PRECISION_DP
:
135 #ifdef SCOPLIB_INT_T_IS_LONG
136 dest
->dp
= (long int)src
;
137 #elif defined( SCOPLIB_INT_T_IS_LONGLONG)
138 dest
->dp
= (long long int)src
;
139 #elif defined( SCOPLIB_INT_T_IS_MP)
140 if(!convert_mpz_fits_llong_p(src
))
141 CONVERTER_error("Conversion of MP-type into longlong. Loss of information");
142 else//loss of precision??
143 dest
->dp
= convert_mpz_get_lld(src
);
147 #ifdef OSL_GMP_IS_HERE
148 case OSL_PRECISION_MP
:
149 #ifdef SCOPLIB_INT_T_IS_LONG
150 mpz_set_si(*(mpz_t
*)dest
->mp
, src
);
151 #elif defined( SCOPLIB_INT_T_IS_LONGLONG)
152 convert_mpz_set_lld(*(mpz_t
*)dest
->mp
, src
);
153 #elif defined( SCOPLIB_INT_T_IS_MP)
154 mpz_set(*(mpz_t
*)dest
->mp
, src
);
157 #endif //OSL_GMP_IS_HERE
160 CONVERTER_error("unknown precision for osl");
168 * Function used in copying osl_relation to a scoplib_matrix.
169 * Assigns a value at an offset in osl_relation, to a value in scoplib_matrix
172 * \param[in] dest address of scoplib_int_t to assign to
173 * \param[in] src_precision precision of the source osl relation
174 * \param[in] src source osl_int_t to assign from
178 void convert_int_assign_osl2scoplib(scoplib_int_t
*dest
,
182 //TODO: replace all typcasts below with (scoplib_int_t*) ??
184 #ifdef SCOPLIB_INT_T_IS_LONG
185 switch(src_precision
){
186 case OSL_PRECISION_SP
:
187 *(long int *)dest
= src
.sp
;
190 case OSL_PRECISION_DP
:
191 if(src
.dp
> LONG_MAX
)
192 CONVERTER_error("Conversion of longlong into long. Loss of information");
194 *(long int *)dest
= src
.dp
; //loss of precision?
197 #ifdef OSL_GMP_IS_HERE
198 case OSL_PRECISION_MP
:
199 if( !mpz_fits_slong_p(*(mpz_t
*)src
.mp
) )
200 CONVERTER_error("Conversion of MP-type into long. Loss of information");
201 else //loss of precision?
202 *(long int *)dest
= mpz_get_si(*(mpz_t
*)src
.mp
);
204 #endif //OSL_GMP_IS_HERE
207 CONVERTER_error("unknown precision for osl");
212 #elif defined( SCOPLIB_INT_T_IS_LONGLONG)
213 switch(src_precision
){
214 case OSL_PRECISION_SP
:
215 *(long long int *)dest
= src
.sp
;
218 case OSL_PRECISION_DP
:
219 *(long long int *)dest
= src
.dp
;
222 #ifdef OSL_GMP_IS_HERE
223 case OSL_PRECISION_MP
:
224 if( !convert_mpz_fits_llong_p(*(mpz_t
*)src
.mp
) ){
225 CONVERTER_error("Conversion of MP-type into longlong. Loss of information");
227 else{ //loss of precision?
228 *(long long int *)dest
= convert_mpz_get_lld(*(mpz_t
*)src
.mp
); //loss of precision?
231 #endif //OSL_GMP_IS_HERE
234 CONVERTER_error("unknown precision for osl");
239 #elif defined( SCOPLIB_INT_T_IS_MP)
240 switch(src_precision
){
241 case OSL_PRECISION_SP
:
242 mpz_set_si(*(mpz_t
*)dest
, src
.sp
);
245 case OSL_PRECISION_DP
:
246 convert_mpz_set_lld(*(mpz_t
*)dest
, src
.dp
);
249 #ifdef OSL_GMP_IS_HERE
250 case OSL_PRECISION_MP
:
251 mpz_set(*(mpz_t
*)dest
, *(mpz_t
*)src
.mp
);
253 #endif //OSL_GMP_IS_HERE
256 CONVERTER_error("unknown precision for osl");
263 #endif //CONVERTER_INT_H