diff options
author | tege <tege@gmplib.org> | 2006-11-04 15:00:39 +0100 |
---|---|---|
committer | tege <tege@gmplib.org> | 2006-11-04 15:00:39 +0100 |
commit | 016693ee61dc5c20ede8cc77b95205767d19af2c (patch) | |
tree | a06fa2ab734ba6157ce1575c7054d779137cbcab /extract-dbl.c | |
parent | f4d7040cec4f22b70ce4e897e30c0a7e883ceecf (diff) | |
download | gmp-016693ee61dc5c20ede8cc77b95205767d19af2c.tar.gz |
Rewrite to handle nails better, and for general optimization.
Diffstat (limited to 'extract-dbl.c')
-rw-r--r-- | extract-dbl.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/extract-dbl.c b/extract-dbl.c index 356a9c577..bffbd5b8c 100644 --- a/extract-dbl.c +++ b/extract-dbl.c @@ -1,6 +1,6 @@ /* __gmp_extract_double -- convert from double to array of mp_limb_t. -Copyright 1996, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +Copyright 1996, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc. This file is part of the GNU MP Library. @@ -85,7 +85,7 @@ __gmp_extract_double (mp_ptr rp, double d) manl = manl << 1; exp--; } - while ((mp_limb_signed_t) manl >= 0); + while ((manl & GMP_LIMB_HIGHBIT) == 0); } #endif #if BITS_PER_PART == 32 @@ -102,7 +102,7 @@ __gmp_extract_double (mp_ptr rp, double d) manl = manl << 1; exp--; } - while ((mp_limb_signed_t) manh >= 0); + while ((manh & GMP_LIMB_HIGHBIT) == 0); } #endif #if BITS_PER_PART != 32 && BITS_PER_PART != 64 @@ -146,23 +146,20 @@ __gmp_extract_double (mp_ptr rp, double d) d *= (4.0 * ((unsigned long int) 1 << (BITS_PER_PART - 2))); #if BITS_PER_PART == 64 manl = d; -#else +#endif +#if BITS_PER_PART == 32 manh = d; manl = (d - manh) * (4.0 * ((unsigned long int) 1 << (BITS_PER_PART - 2))); #endif } #endif /* IEEE */ - /* Up until here, we have ignored the actual limb size. Remains - to split manh,,manl into an array of LIMBS_PER_DOUBLE limbs. - */ - sc = (unsigned) (exp + 64 * GMP_NUMB_BITS) % GMP_NUMB_BITS; /* We add something here to get rounding right. */ exp = (exp + 64 * GMP_NUMB_BITS) / GMP_NUMB_BITS - 64 * GMP_NUMB_BITS / GMP_NUMB_BITS + 1; -#if LIMBS_PER_DOUBLE == 2 +#if BITS_PER_PART == 64 && LIMBS_PER_DOUBLE == 2 #if GMP_NAIL_BITS == 0 if (sc != 0) { @@ -198,7 +195,35 @@ __gmp_extract_double (mp_ptr rp, double d) #endif #endif -#if LIMBS_PER_DOUBLE == 3 +#if BITS_PER_PART == 64 && LIMBS_PER_DOUBLE == 3 + if (sc > GMP_NAIL_BITS) + { + rp[2] = manl >> (GMP_LIMB_BITS - sc); + rp[1] = (manl << sc - GMP_NAIL_BITS) & GMP_NUMB_MASK; + if (sc >= 2 * GMP_NAIL_BITS) + rp[0] = 0; + else + rp[0] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS + sc) & GMP_NUMB_MASK; + } + else + { + if (sc == 0) + { + rp[2] = manl >> GMP_NAIL_BITS; + rp[1] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS) & GMP_NUMB_MASK; + rp[0] = 0; + exp--; + } + else + { + rp[2] = manl >> (GMP_LIMB_BITS - sc); + rp[1] = (manl >> GMP_NAIL_BITS - sc) & GMP_NUMB_MASK; + rp[0] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS + sc) & GMP_NUMB_MASK; + } + } +#endif + +#if BITS_PER_PART == 32 && LIMBS_PER_DOUBLE == 3 #if GMP_NAIL_BITS == 0 if (sc != 0) { @@ -230,7 +255,7 @@ __gmp_extract_double (mp_ptr rp, double d) { rp[2] = manh >> GMP_NAIL_BITS; rp[1] = ((manh << GMP_NUMB_BITS - GMP_NAIL_BITS) | (manl >> 2 * GMP_NAIL_BITS)) & GMP_NUMB_MASK; - rp[0] = 0; + rp[0] = (manl << GMP_NUMB_BITS - 2 * GMP_NAIL_BITS) & GMP_NUMB_MASK; exp--; } else @@ -244,7 +269,7 @@ __gmp_extract_double (mp_ptr rp, double d) #endif #endif -#if LIMBS_PER_DOUBLE > 3 +#if BITS_PER_PART == 32 && LIMBS_PER_DOUBLE > 3 if (sc == 0) { int i; |