summaryrefslogtreecommitdiff
path: root/src/set_d64.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2018-09-05 13:18:11 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2018-09-05 13:18:11 +0000
commit528cf1edba7cc556a7ac31cd006d781097fcf737 (patch)
tree72f17e3a94121cd7adb06775df9ddbd497b05176 /src/set_d64.c
parent5309fb1ee65a0a43c5dc9712bad69f836f08f458 (diff)
downloadmpfr-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
Diffstat (limited to 'src/set_d64.c')
-rw-r--r--src/set_d64.c29
1 files changed, 20 insertions, 9 deletions
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;
}