diff options
author | John McCall <rjmccall@apple.com> | 2009-12-24 23:18:09 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-12-24 23:18:09 +0000 |
commit | 6a09affdf62fccbd190ca6e9cac0cb065b5f2677 (patch) | |
tree | cc8026e6624f0de46a1c8a4e21cdd4d9fb284f41 /lib/Support | |
parent | c883ad2dd8d4861f6c2cbc89f079152a159778c8 (diff) |
Implement support for converting to string at "natural precision", and fix some
major bugs in long-precision conversion.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92150 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/APFloat.cpp | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 5f748a2c24..1e6d22f18e 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -3253,7 +3253,7 @@ namespace { // Truncate the significand down to its active bit count, but // don't try to drop below 32. - unsigned newPrecision = std::min(32U, significand.getActiveBits()); + unsigned newPrecision = std::max(32U, significand.getActiveBits()); significand.trunc(newPrecision); } @@ -3339,6 +3339,16 @@ void APFloat::toString(SmallVectorImpl<char> &Str, partCountForBits(semantics->precision), significandParts()); + // Set FormatPrecision if zero. We want to do this before we + // truncate trailing zeros, as those are part of the precision. + if (!FormatPrecision) { + // It's an interesting question whether to use the nominal + // precision or the active precision here for denormals. + + // FormatPrecision = ceil(significandBits / lg_2(10)) + FormatPrecision = (semantics->precision * 59 + 195) / 196; + } + // Ignore trailing binary zeros. int trailingZeros = significand.countTrailingZeros(); exp += trailingZeros; @@ -3361,9 +3371,10 @@ void APFloat::toString(SmallVectorImpl<char> &Str, // To avoid overflow, we have to operate on numbers large // enough to store N * 5^e: // log2(N * 5^e) == log2(N) + e * log2(5) - // <= semantics->precision + e * 2.5 - // (log_2(5) ~ 2.321928) - unsigned precision = semantics->precision + 5 * texp / 2; + // <= semantics->precision + e * 137 / 59 + // (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59) + + unsigned precision = semantics->precision + 137 * texp / 59; // Multiply significand by 5^e. // N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8) @@ -3411,30 +3422,29 @@ void APFloat::toString(SmallVectorImpl<char> &Str, unsigned NDigits = buffer.size(); - // Check whether we should a non-scientific format. + // Check whether we should use scientific notation. bool FormatScientific; if (!FormatMaxPadding) FormatScientific = true; else { - unsigned Padding; if (exp >= 0) { - // 765e3 == 765000 - // ^^^ - Padding = (unsigned) exp; + // 765e3 --> 765000 + // ^^^ + // But we shouldn't make the number look more precise than it is. + FormatScientific = ((unsigned) exp > FormatMaxPadding || + NDigits + (unsigned) exp > FormatPrecision); } else { - unsigned Margin = (unsigned) -exp; - if (Margin < NDigits) { + // Power of the most significant digit. + int MSD = exp + (int) (NDigits - 1); + if (MSD >= 0) { // 765e-2 == 7.65 - Padding = 0; + FormatScientific = false; } else { // 765e-5 == 0.00765 // ^ ^^ - Padding = Margin + 1 - NDigits; + FormatScientific = ((unsigned) -MSD) > FormatMaxPadding; } } - - FormatScientific = (Padding > FormatMaxPadding || - Padding + NDigits > FormatPrecision); } // Scientific formatting is pretty straightforward. |