[llvm-commits] CVS: llvm/lib/Support/APInt.cpp

Reid Spencer reid at x10sys.com
Fri Apr 13 12:19:24 PDT 2007



Changes in directory llvm/lib/Support:

APInt.cpp updated: 1.76 -> 1.77
---
Log message:

Implement a getBitsNeeded method to determine how many bits are needed to
represent a string in binary form by an APInt.


---
Diffs of the changes:  (+37 -0)

 APInt.cpp |   37 +++++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+)


Index: llvm/lib/Support/APInt.cpp
diff -u llvm/lib/Support/APInt.cpp:1.76 llvm/lib/Support/APInt.cpp:1.77
--- llvm/lib/Support/APInt.cpp:1.76	Wed Apr 11 08:00:04 2007
+++ llvm/lib/Support/APInt.cpp	Fri Apr 13 14:19:07 2007
@@ -659,6 +659,43 @@
   return *this;
 }
 
+uint32_t APInt::getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) {
+  assert(str != 0 && "Invalid value string");
+  assert(slen > 0 && "Invalid string length");
+
+  // Each computation below needs to know if its negative
+  uint32_t isNegative = str[0] == '-';
+  if (isNegative) {
+    slen--;
+    str++;
+  }
+  // For radixes of power-of-two values, the bits required is accurately and
+  // easily computed
+  if (radix == 2)
+    return slen + isNegative;
+  if (radix == 8)
+    return slen * 3 + isNegative;
+  if (radix == 16)
+    return slen * 4 + isNegative;
+
+  // Otherwise it must be radix == 10, the hard case
+  assert(radix == 10 && "Invalid radix");
+
+  // This is grossly inefficient but accurate. We could probably do something
+  // with a computation of roughly slen*64/20 and then adjust by the value of
+  // the first few digits. But, I'm not sure how accurate that could be.
+
+  // Compute a sufficient number of bits that is always large enough but might
+  // be too large. This avoids the assertion in the constructor.
+  uint32_t sufficient = slen*64/18;
+
+  // Convert to the actual binary value.
+  APInt tmp(sufficient, str, slen, radix);
+
+  // Compute how many bits are required.
+  return isNegative + tmp.logBase2();
+}
+
 uint64_t APInt::getHashValue() const {
   // Put the bit width into the low order bits.
   uint64_t hash = BitWidth;






More information about the llvm-commits mailing list