=================================================================== RCS file: /home/cvs/OpenXM/src/ox_toolkit/ox.c,v retrieving revision 1.36 retrieving revision 1.48 diff -u -p -r1.36 -r1.48 --- OpenXM/src/ox_toolkit/ox.c 2013/10/20 15:29:12 1.36 +++ OpenXM/src/ox_toolkit/ox.c 2016/06/30 01:14:00 1.48 @@ -1,21 +1,39 @@ /* -*- mode: C; coding: euc-japan -*- */ -/* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.35 2013/10/20 14:58:20 iwane Exp $ */ +/* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.47 2016/06/29 05:07:23 ohara Exp $ */ /* This module includes functions for sending/receiveng CMO's. - Some commnets is written in Japanese by the EUC-JP coded - character set. */ #include #include #include #include -#include #include -#include #include +#include +#if !defined(_MSC_VER) +#include +#include +#endif +#include +/* XXX : defined in mpfr-impl.h */ +#define MPFR_PREC(x) ((x)->_mpfr_prec) +#define MPFR_EXP(x) ((x)->_mpfr_exp) +#define MPFR_MANT(x) ((x)->_mpfr_d) +#define RAT_CEIL(nm,dn) (((nm)+(dn)-1)/((dn))) +#define MPFR_LIMB_SIZE_REAL(x) (RAT_CEIL(MPFR_PREC((x)),sizeof(mp_limb_t)*CHAR_BIT) * (sizeof(mp_limb_t)/sizeof(int)) ) +#define MPFR_LIMB_SIZE_BODY(x) (RAT_CEIL(MPFR_PREC((x)),sizeof(unsigned int)*CHAR_BIT)) + +#if SIZEOF_LONG==4 +typedef long long L64; +typedef unsigned long long UL64; +#else +typedef long L64; +typedef unsigned long UL64; +#endif + #include "mysocket.h" #include "ox_toolkit.h" #include "parse.h" @@ -54,6 +72,10 @@ static cmo_zz* receive_cmo_zz(OXFILE *oxfp); static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz); static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c); static int send_mpz(OXFILE *oxfp, mpz_ptr mpz); +static cmo_bf* receive_cmo_bf(OXFILE *oxfp); +static void receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr); +static int send_cmo_bf(OXFILE *oxfp, cmo_bf* c); +static int send_mpfr(OXFILE *oxfp, mpfr_ptr mpfr); /* hook functions. (yet not implemented) */ static hook_t hook_before_send_cmo = NULL; @@ -218,6 +240,24 @@ static cmo_qq* receive_cmo_qq(OXFILE *oxfp) return new_cmo_qq_set_mpz(num, den); } +static cmo_bf* receive_cmo_bf(OXFILE *oxfp) +{ + mpfr_t num; + mpfr_init(num); + receive_mpfr(oxfp, num); + return new_cmo_bf_set_mpfr(num); +} + +static cmo_complex* receive_cmo_complex(OXFILE *oxfp) +{ + cmo *re, *im; + + re = receive_cmo(oxfp); + im = receive_cmo(oxfp); + return new_cmo_complex_set_re_im(re,im); +} + + static cmo_zero* receive_cmo_zero(OXFILE *oxfp) { return new_cmo_zero(); @@ -342,6 +382,12 @@ cmo *receive_cmo_tag(OXFILE *oxfp, int tag) case CMO_QQ: m = (cmo *)receive_cmo_qq(oxfp); break; + case CMO_BIGFLOAT32: + m = (cmo *)receive_cmo_bf(oxfp); + break; + case CMO_COMPLEX: + m = (cmo *)receive_cmo_complex(oxfp); + break; case CMO_ZERO: m = (cmo *)receive_cmo_zero(oxfp); break; @@ -393,8 +439,10 @@ static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz) int *ptr; if (n == 1) { resize_mpz(mpz, size); - } else { + } else if (size >= 0) { resize_mpz(mpz, (size+1) / n); + } else { + resize_mpz(mpz, (size-1) / n); } ptr = (int *)mpz->_mp_d; @@ -619,6 +667,19 @@ static int send_cmo_qq(OXFILE *oxfp, cmo_qq* c) return 0; } +static int send_cmo_bf(OXFILE *oxfp, cmo_bf* c) +{ + send_mpfr(oxfp, c->mpfr); + return 0; +} + +static int send_cmo_complex(OXFILE *oxfp, cmo_complex* c) +{ + send_cmo(oxfp, c->re); + send_cmo(oxfp, c->im); + return 0; +} + static int send_cmo_recursive_polynomial(OXFILE *oxfp, cmo_recursive_polynomial* c) { send_cmo(oxfp, (cmo *)c->ringdef); @@ -685,6 +746,12 @@ void send_cmo(OXFILE *oxfp, cmo* c) case CMO_QQ: send_cmo_qq(oxfp, (cmo_qq *)c); break; + case CMO_BIGFLOAT32: + send_cmo_bf(oxfp, (cmo_bf *)c); + break; + case CMO_COMPLEX: + send_cmo_complex(oxfp, (cmo_complex *)c); + break; case CMO_DISTRIBUTED_POLYNOMIAL: send_cmo_distributed_polynomial(oxfp, (cmo_distributed_polynomial *)c); break; @@ -715,8 +782,62 @@ static int send_mpz(OXFILE *oxfp, mpz_ptr mpz) int n = sizeof(mpz->_mp_d[0]) / sizeof(int); int len = abs(mpz->_mp_size) * n; int *ptr = (int *)mpz->_mp_d; - send_int32(oxfp, mpz->_mp_size * n); + int size; + if (len > 0 && ptr[len-1] == 0) { + len--; + } + size = mpz->_mp_size < 0 ? -len : len; + send_int32(oxfp, size); for(i=0; isend_double(oxfp,((double *)&a)[0]); +} + +UL64 receive_int64(OXFILE *oxfp) +{ + double d = receive_double(oxfp); + return ((UL64 *)&d)[0]; +} + +static void receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr) +{ + int sgn,prec,exp,len_r,len,i; + unsigned int *ptr; + + prec = receive_int32(oxfp); + sgn = receive_int32(oxfp); + exp = receive_int32(oxfp); + len = receive_int32(oxfp); + mpfr_init2(mpfr,prec); /* initialized by NaN */ + MPFR_SIGN(mpfr) = sgn; + MPFR_EXP(mpfr) = exp; + *(MPFR_MANT(mpfr))=0; /* initialized by 0 */ + ptr = (unsigned int *)MPFR_MANT(mpfr); + len_r = MPFR_LIMB_SIZE_REAL(mpfr); + for(i=(len_r-len); i