diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2018-09-05 13:18:11 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2018-09-05 13:18:11 +0000 |
commit | 528cf1edba7cc556a7ac31cd006d781097fcf737 (patch) | |
tree | 72f17e3a94121cd7adb06775df9ddbd497b05176 | |
parent | 5309fb1ee65a0a43c5dc9712bad69f836f08f458 (diff) | |
download | mpfr-528cf1edba7cc556a7ac31cd006d781097fcf737.tar.gz |
[src/get_d64.c] fixed for 16-bit limb
[src/set_d64.c] likewise
[tests/tget_set_d64.c] improved error message
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@13139 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | src/get_d64.c | 32 | ||||
-rw-r--r-- | src/set_d64.c | 29 | ||||
-rw-r--r-- | tests/tget_set_d64.c | 4 |
3 files changed, 44 insertions, 21 deletions
diff --git a/src/get_d64.c b/src/get_d64.c index 48ae01017..8f0241c4b 100644 --- a/src/get_d64.c +++ b/src/get_d64.c @@ -185,7 +185,7 @@ get_decimal64_max (int negative) static _Decimal64 string_to_Decimal64 (char *s) { - long int exp = 0; + long int exp; char m[17]; long n = 0; /* mantissa length */ char *endptr[1]; @@ -266,19 +266,31 @@ string_to_Decimal64 (char *s) x.s.manl |= (d3 << 20) | (d4 << 10) | d5; #else /* BID format */ { - mp_size_t rn; - mp_limb_t rp[2]; + unsigned int rp[2]; /* rp[0] and rp[1] should contain at least 32 bits */ +#define NLIMBS (64 / GMP_NUMB_BITS) + mp_limb_t sp[NLIMBS]; + mp_size_t sn; int case_i = strcmp (m, "9007199254740992") < 0; for (n = 0; n < 16; n++) m[n] -= '0'; - rn = mpn_set_str (rp, (unsigned char *) m, 16, 10); - if (rn == 1) - rp[1] = 0; -#if GMP_NUMB_BITS > 32 - rp[1] = rp[1] << (GMP_NUMB_BITS - 32); - rp[1] |= rp[0] >> 32; - rp[0] &= 4294967295UL; + sn = mpn_set_str (sp, (unsigned char *) m, 16, 10); + while (sn < NLIMBS) + sp[sn++] = 0; + /* now convert {sp, sn} to {rp, 2} */ +#if GMP_NUMB_BITS >= 64 + MPFR_ASSERTD(sn <= 1); + rp[0] = sp[0] & 4294967295UL; + rp[1] = sp[0] >> 32; +#elif GMP_NUMB_BITS == 32 + MPFR_ASSERTD(sn <= 2); + rp[0] = sp[0]; + rp[1] = sp[1]; +#elif GMP_NUMB_BITS == 16 + rp[0] = sp[0] | ((unsigned int) sp[1] << 16); + rp[1] = sp[2] | ((unsigned int) sp[3] << 16); +#else +#error "GMP_NUMB_BITS should be 16, 32, or >= 64" #endif if (case_i) { /* s < 2^53: case i) */ diff --git a/src/set_d64.c b/src/set_d64.c index 883dd8f15..304098b5a 100644 --- a/src/set_d64.c +++ b/src/set_d64.c @@ -123,8 +123,10 @@ decimal64_to_string (char *s, _Decimal64 d) #ifdef DPD_FORMAT unsigned int d0, d1, d2, d3, d4, d5; #else - mp_limb_t rp[2]; - mp_size_t rn; + unsigned int rp[2]; /* rp[0] and rp[1] should contain at least 32 bits */ +#define NLIMBS (64 / GMP_NUMB_BITS) + mp_limb_t sp[NLIMBS]; + mp_size_t sn; #endif /* now convert BID or DPD to string */ @@ -201,15 +203,24 @@ decimal64_to_string (char *s, _Decimal64 d) rp[1] &= 524287; /* 2^19-1: cancel G[11] */ rp[1] |= 2097152; /* add 2^21 */ } + /* now convert {rp, 2} to {sp, NLIMBS} */ #if GMP_NUMB_BITS >= 64 - rp[0] |= rp[1] << 32; - rn = 1; + sp[0] = MPFR_LIMB(rp[0]) | MPFR_LIMB_LSHIFT(rp[1],32); +#elif GMP_NUMB_BITS == 32 + sp[0] = rp[0]; + sp[1] = rp[1]; +#elif GMP_NUMB_BITS == 16 + sp[0] = MPFR_LIMB(rp[0]); + sp[1] = MPFR_LIMB(rp[0] >> 16); + sp[2] = MPFR_LIMB(rp[1]); + sp[3] = MPFR_LIMB(rp[1] >> 16); #else - rn = 2; +#error "GMP_NUMB_BITS should be 16, 32, or >= 64" #endif - while (rn > 0 && rp[rn - 1] == 0) - rn --; - if (rn == 0) + sn = NLIMBS; + while (sn > 0 && sp[sn - 1] == 0) + sn --; + if (sn == 0) { zero: *t = 0; @@ -217,7 +228,7 @@ decimal64_to_string (char *s, _Decimal64 d) } else { - i = mpn_get_str ((unsigned char*) t, 10, rp, rn); + i = mpn_get_str ((unsigned char*) t, 10, sp, sn); if (i > 16) /* non-canonical encoding: return zero */ goto zero; } diff --git a/tests/tget_set_d64.c b/tests/tget_set_d64.c index 4755e65c2..372998ccc 100644 --- a/tests/tget_set_d64.c +++ b/tests/tget_set_d64.c @@ -33,7 +33,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., # define DEC64_MAX 9.999999999999999E384dd #endif -#if _MPFR_IEEE_FLOATS +#if _MPFR_IEEE_FLOATSxxx static void print_decimal64 (_Decimal64 d) { @@ -533,7 +533,7 @@ check_random_bytes (void) printf ("check_random_bytes failed\n"); printf ("x.d="); print_decimal64 (x.d); printf ("y="); mpfr_dump (y); - printf ("e="); print_decimal64 (e); + printf ("e ="); print_decimal64 (e); exit (1); } } |