diff options
author | Neil Booth <neil@daikokuya.co.uk> | 2007-10-07 12:07:53 +0000 |
---|---|---|
committer | Neil Booth <neil@daikokuya.co.uk> | 2007-10-07 12:07:53 +0000 |
commit | 643ce59495702ef29573b725d7431638be1c136a (patch) | |
tree | 37b6c79e00a563cbd566a148813f1b9e0f8ff1da /lib/Support | |
parent | ccf596a53e16ea221a9bf8b3874a7d6afa71f1f4 (diff) | |
download | external_llvm-643ce59495702ef29573b725d7431638be1c136a.zip external_llvm-643ce59495702ef29573b725d7431638be1c136a.tar.gz external_llvm-643ce59495702ef29573b725d7431638be1c136a.tar.bz2 |
Reimplement convertFromUnsignedInteger so it is passed a const bignum.
It used to modify its argument in-place.
This interface is saner and the implementation more efficient. It will
be needed for decimal->binary conversion.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42733 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/APFloat.cpp | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 5e3504b1..7e56c84 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -1548,30 +1548,41 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width, return opInexact; } +/* Convert an unsigned integer SRC to a floating point number, + rounding according to ROUNDING_MODE. The sign of the floating + point number is not modified. */ APFloat::opStatus -APFloat::convertFromUnsignedInteger(integerPart *parts, - unsigned int partCount, - roundingMode rounding_mode) +APFloat::convertFromUnsignedParts(const integerPart *src, + unsigned int srcCount, + roundingMode rounding_mode) { - unsigned int msb, precision; + unsigned int dstCount; lostFraction lost_fraction; - - msb = APInt::tcMSB(parts, partCount) + 1; - precision = semantics->precision; + integerPart *dst; category = fcNormal; - exponent = precision - 1; + exponent = semantics->precision - 1; - if(msb > precision) { - exponent += (msb - precision); - lost_fraction = shiftRight(parts, partCount, msb - precision); - msb = precision; - } else - lost_fraction = lfExactlyZero; + dst = significandParts(); + dstCount = partCount(); - /* Copy the bit image. */ - zeroSignificand(); - APInt::tcAssign(significandParts(), parts, partCountForBits(msb)); + /* We need to capture the non-zero most significant parts. */ + while (srcCount > dstCount && src[srcCount - 1] == 0) + srcCount--; + + /* Copy the bit image of as many parts as we can. If we are wider, + zero-out remaining parts. */ + if (dstCount >= srcCount) { + APInt::tcAssign(dst, src, srcCount); + while (srcCount < dstCount) + dst[srcCount++] = 0; + lost_fraction = lfExactlyZero; + } else { + exponent += (srcCount - dstCount) * integerPartWidth; + APInt::tcAssign(dst, src + (srcCount - dstCount), dstCount); + lost_fraction = lostFractionThroughTruncation(src, srcCount, + dstCount * integerPartWidth); + } return normalize(rounding_mode, lost_fraction); } @@ -1594,7 +1605,7 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts, } APInt::tcAssign(copy, api.getRawData(), partCount); - status = convertFromUnsignedInteger(copy, partCount, rounding_mode); + status = convertFromUnsignedParts(copy, partCount, rounding_mode); return status; } |