modified autogen.sh to remove reference to osl/
[converter.git] / source / converter_int.c
blob4990a553df84cda2d270d621e74b79c2121bab3b
1 #ifndef CONVERTER_INT_H
2 #define CONVERTER_INT_H
4 #include <stdlib.h>
5 #include <limits.h>
6 #include <math.h>
9 #ifdef OSL_GMP_IS_HERE
10 #include <gmp.h>
11 //#elif defined( defined(SCOPLIB_INT_T_IS_MP)
12 //#include <gmp.h>
13 #endif
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){
29 mpz_t llMax;
30 char *szULL = NULL;
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)){
37 free(szULL);
38 return 0;
40 else { // what about LLONG_MIN??
41 free(szULL);
42 return 1;
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){
56 char *szLLD = NULL;
57 CONVERTER_malloc(szLLD, char *, 2 + ceil(log10(LLONG_MAX)));
58 if(szLLD){
59 mpz_get_str(szLLD, 10, x);
60 unsigned long long lld=strtoll(szLLD, NULL, 10);
61 free(szLLD);
62 return lld;
64 else{
65 free(szLLD);
66 return 0LL;
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
77 //is a pointer.
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){
91 char *szULL=NULL;
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);
97 free(szULL);
98 return;
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
111 * \return void
114 void convert_int_assign_scoplib2osl(int dest_precision, osl_int_p dest,
115 scoplib_int_t src ){
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)
122 if(src > LONG_MAX)
123 CONVERTER_error("Conversion of longlong into long. Loss of information");
124 else
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");
129 else
130 dest->sp = mpz_get_si(src); // loss of precision??
131 #endif
132 break;
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);
144 #endif
145 break;
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);
155 #endif
156 break;
157 #endif //OSL_GMP_IS_HERE
159 default:
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
175 * \return void
178 void convert_int_assign_osl2scoplib(scoplib_int_t *dest,
179 int src_precision,
180 osl_int_t src){
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;
188 break;
190 case OSL_PRECISION_DP:
191 if(src.dp > LONG_MAX)
192 CONVERTER_error("Conversion of longlong into long. Loss of information");
193 else
194 *(long int *)dest = src.dp; //loss of precision?
195 break;
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);
203 break;
204 #endif //OSL_GMP_IS_HERE
206 default:
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;
216 break;
218 case OSL_PRECISION_DP:
219 *(long long int *)dest = src.dp;
220 break;
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?
230 break;
231 #endif //OSL_GMP_IS_HERE
233 default:
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);
243 break;
245 case OSL_PRECISION_DP:
246 convert_mpz_set_lld(*(mpz_t *)dest, src.dp);
247 break;
249 #ifdef OSL_GMP_IS_HERE
250 case OSL_PRECISION_MP:
251 mpz_set(*(mpz_t *)dest, *(mpz_t *)src.mp);
252 break;
253 #endif //OSL_GMP_IS_HERE
255 default:
256 CONVERTER_error("unknown precision for osl");
259 #endif
263 #endif //CONVERTER_INT_H