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
This commit is contained in:
Neil Booth 2007-10-07 12:07:53 +00:00
parent ccf596a53e
commit 643ce59495
2 changed files with 31 additions and 20 deletions

View File

@ -266,7 +266,7 @@ namespace llvm {
cmpResult compareAbsoluteValue(const APFloat &) const; cmpResult compareAbsoluteValue(const APFloat &) const;
opStatus handleOverflow(roundingMode); opStatus handleOverflow(roundingMode);
bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const; bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
opStatus convertFromUnsignedInteger(integerPart *, unsigned int, opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
roundingMode); roundingMode);
opStatus convertFromHexadecimalString(const char *, roundingMode); opStatus convertFromHexadecimalString(const char *, roundingMode);
char *convertNormalToHexString(char *, unsigned int, bool, char *convertNormalToHexString(char *, unsigned int, bool,

View File

@ -1548,30 +1548,41 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width,
return opInexact; 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::opStatus
APFloat::convertFromUnsignedInteger(integerPart *parts, APFloat::convertFromUnsignedParts(const integerPart *src,
unsigned int partCount, unsigned int srcCount,
roundingMode rounding_mode) roundingMode rounding_mode)
{ {
unsigned int msb, precision; unsigned int dstCount;
lostFraction lost_fraction; lostFraction lost_fraction;
integerPart *dst;
msb = APInt::tcMSB(parts, partCount) + 1;
precision = semantics->precision;
category = fcNormal; category = fcNormal;
exponent = precision - 1; exponent = semantics->precision - 1;
if(msb > precision) { dst = significandParts();
exponent += (msb - precision); dstCount = partCount();
lost_fraction = shiftRight(parts, partCount, msb - precision);
msb = precision; /* We need to capture the non-zero most significant parts. */
} else 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; lost_fraction = lfExactlyZero;
} else {
/* Copy the bit image. */ exponent += (srcCount - dstCount) * integerPartWidth;
zeroSignificand(); APInt::tcAssign(dst, src + (srcCount - dstCount), dstCount);
APInt::tcAssign(significandParts(), parts, partCountForBits(msb)); lost_fraction = lostFractionThroughTruncation(src, srcCount,
dstCount * integerPartWidth);
}
return normalize(rounding_mode, lost_fraction); return normalize(rounding_mode, lost_fraction);
} }
@ -1594,7 +1605,7 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
} }
APInt::tcAssign(copy, api.getRawData(), partCount); APInt::tcAssign(copy, api.getRawData(), partCount);
status = convertFromUnsignedInteger(copy, partCount, rounding_mode); status = convertFromUnsignedParts(copy, partCount, rounding_mode);
return status; return status;
} }