Fix APFloat from string conversion for Inf

The method IEEEFloat::convertFromStringSpecials() does not recognize
the "+Inf" and "-Inf" strings but these strings are printed for
the double Infinities by the IEEEFloat::toString().

This patch adds the "+Inf" and "-Inf" strings to the list of recognized
patterns in IEEEFloat::convertFromStringSpecials().

Re-landing after fix.

Reviewers: sberg, bogner, majnemer, timshen, rnk, skatkov, gottesmm, bkramer, scanon, anna
Reviewed By: anna
Subscribers: mkazantsev, FlameTop, llvm-commits, reames, apilipenko
Differential Revision: https://reviews.llvm.org/D38030

llvm-svn: 321054
This commit is contained in:
Serguei Katkov 2017-12-19 04:27:39 +00:00
parent 63a328c30c
commit 768d6dd087
4 changed files with 26 additions and 4 deletions

View File

@ -2546,12 +2546,12 @@ IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) {
}
bool IEEEFloat::convertFromStringSpecials(StringRef str) {
if (str.equals("inf") || str.equals("INFINITY")) {
if (str.equals("inf") || str.equals("INFINITY") || str.equals("+Inf")) {
makeInf(false);
return true;
}
if (str.equals("-inf") || str.equals("-INFINITY")) {
if (str.equals("-inf") || str.equals("-INFINITY") || str.equals("-Inf")) {
makeInf(true);
return true;
}

View File

@ -586,7 +586,7 @@ bool StringRef::getAsDouble(double &Result, bool AllowInexact) const {
APFloat::opStatus Status =
F.convertFromString(*this, APFloat::rmNearestTiesToEven);
if (Status != APFloat::opOK) {
if (!AllowInexact || Status != APFloat::opInexact)
if (!AllowInexact || !(Status & APFloat::opInexact))
return true;
}

View File

@ -849,6 +849,23 @@ TEST(APFloatTest, fromDecimalString) {
EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));
}
TEST(APFloatTest, fromToStringSpecials) {
auto expects = [] (const char *first, const char *second) {
std::string roundtrip = convertToString(convertToDoubleFromString(second), 0, 3);
EXPECT_STREQ(first, roundtrip.c_str());
};
expects("+Inf", "+Inf");
expects("+Inf", "INFINITY");
expects("+Inf", "inf");
expects("-Inf", "-Inf");
expects("-Inf", "-INFINITY");
expects("-Inf", "-inf");
expects("NaN", "NaN");
expects("NaN", "nan");
expects("NaN", "-NaN");
expects("NaN", "-nan");
}
TEST(APFloatTest, fromHexadecimalString) {
EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());
EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p0").convertToDouble());

View File

@ -875,7 +875,12 @@ struct GetDoubleStrings {
{"0.0", false, false, 0.0},
{"-0.0", false, false, -0.0},
{"123.45", false, true, 123.45},
{"123.45", true, false, 123.45}};
{"123.45", true, false, 123.45},
{"1.8e308", true, false, std::numeric_limits<double>::infinity()},
{"1.8e308", false, true, std::numeric_limits<double>::infinity()},
{"0x0.0000000000001P-1023", false, true, 0.0},
{"0x0.0000000000001P-1023", true, false, 0.0},
};
TEST(StringRefTest, getAsDouble) {
for (const auto &Entry : DoubleStrings) {