From bc3e15e46f6dee959bbeb68dd266d4c69543e1f8 Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Fri, 11 Sep 2009 22:54:27 +0200 Subject: [PATCH] Fix double_approx(const cl_RA& x) on 64-Bit platforms. When we extended immediate types on 64-bit platforms back for CLN 1.2.0, we broke the assumption that integers 2^53..2^55-1 are bignums. This lead to segfaults when approximating a non-integer cl_RA to double, as reported by Igor Khavkine . --- src/float/dfloat/conv/cl_RA_to_double.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/float/dfloat/conv/cl_RA_to_double.cc b/src/float/dfloat/conv/cl_RA_to_double.cc index dac7ff0..6a138e2 100644 --- a/src/float/dfloat/conv/cl_RA_to_double.cc +++ b/src/float/dfloat/conv/cl_RA_to_double.cc @@ -70,12 +70,16 @@ double double_approx (const cl_RA& x) } // Division zaehler/nenner durchführen: var cl_I_div_t q_r = cl_divide(zaehler,nenner); - var cl_I& q = q_r.quotient; + var cl_I& q = q_r.quotient; // 2^53 <= q < 2^55 var cl_I& r = q_r.remainder; - // 2^53 <= q < 2^55, also ist q Bignum mit ceiling(55/intDsize) Digits. - var const uintD* ptr = BN_MSDptr(q); #if (cl_word_size==64) - var uint64 mant = get_max64_Dptr(55,ptr); + # if (cl_value_len-1 > 55) + var uint64 mant = FN_to_V(q); // q is a fixnum! + # elif (cl_value_len-1 <= 53) + var uint64 mant = get_max64_Dptr(55,BN_MSDptr(q)); // q is a bignum! + # else + var uint64 mant = fixnump(q) ? FN_to_V(q) : get_max64_Dptr(55,BN_MSDptr(q)); + # endif if (mant >= bit(DF_mant_len+2)) // 2^54 <= q < 2^55, schiebe um 2 Bits nach rechts { var uint64 rounding_bits = mant & (bit(2)-1); @@ -126,6 +130,8 @@ double double_approx (const cl_RA& x) } return u.machine_double; #else + // q is bignum with ceiling(55/intDsize) Digits. + var const uintD* ptr = BN_MSDptr(q); var uint32 manthi = get_max32_Dptr(23,ptr); var uint32 mantlo = get_32_Dptr(ptr mspop ceiling(23,intDsize)); if (manthi >= bit(DF_mant_len-32+2))