Reimplement convertFromUnsignedInteger so it is passed a const bignum.
authorNeil Booth <neil@daikokuya.co.uk>
Sun, 7 Oct 2007 12:07:53 +0000 (12:07 +0000)
committerNeil Booth <neil@daikokuya.co.uk>
Sun, 7 Oct 2007 12:07:53 +0000 (12:07 +0000)
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

include/llvm/ADT/APFloat.h
lib/Support/APFloat.cpp

index 7505269c68c8b023130a87541a8cdcb6dadfcec5..67c979cece5f0740e1ce814f069ba829c3e807c2 100644 (file)
@@ -266,8 +266,8 @@ namespace llvm {
     cmpResult compareAbsoluteValue(const APFloat &) const;
     opStatus handleOverflow(roundingMode);
     bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
-    opStatus convertFromUnsignedInteger(integerPart *, unsigned int,
-                                        roundingMode);
+    opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
+                                      roundingMode);
     opStatus convertFromHexadecimalString(const char *, roundingMode);
     char *convertNormalToHexString(char *, unsigned int, bool,
                                    roundingMode) const;
index 5e3504b19a5f9c1751955fc68e8616949989fde9..7e56c849a5ec985e88f272afbf29f3689fa1aa4e 100644 (file)
@@ -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;
 }