[PATCH] Support/APFloat, fix assert on convertFromString(toString(infty))

Duncan P. N. Exon Smith dexonsmith at apple.com
Sun Mar 22 09:39:06 PDT 2015


> On 2015 Mar 21, at 16:17, Johan Engelen <jbc.engelen at swissonline.ch> wrote:
> 
> On 17-3-2015 18:46, Duncan P. N. Exon Smith wrote:
>>> On 2015-Mar-16, at 15:54, Johan Engelen <jbc.engelen at swissonline.ch> wrote:
>>> 
>>> Hello,
>>>  Here is a patch for /lib/Support/APFloat.cpp that fixes an assert when the output of APFloat::toString() is fed back into APFloat::convertFromString().
>>> 
>>> For infinity, toString() outputs a string with upper case "Inf", whereas convertFromString() only accepts lowercase "inf".
>>> 
>>> The patch adds "Inf" and "-Inf" to the accepted strings in convertFromString(), and modifies the output from toString() to "Inf" instead of "+Inf" for positive infinity.
>> Testcase?  I suggest something in unittests/ADT/APFloatTest.cpp.
> 
> Thanks for your email. Sorry for not providing tests, I'm new to LLVM development.
> Attached is an improved patch with unittests added. I added an extra change that adds the sign of NaN to the string output.
> 
> kind regards,
>  Johan
> 
> 
> <APFloat_v2.patch>

Thanks for continuing to work on this.  Code changes look fine to me
still, but I have a few comments on the tests.

> Index: unittests/ADT/APFloatTest.cpp
> ===================================================================
> --- unittests/ADT/APFloatTest.cpp	(revision 232903)
> +++ unittests/ADT/APFloatTest.cpp	(working copy)
> @@ -947,6 +947,19 @@
>    ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1));
>    ASSERT_EQ("8.7318340000000001E+2", convertToString(873.1834, 0, 0));
>    ASSERT_EQ("1.7976931348623157E+308", convertToString(1.7976931348623157E+308, 0, 0));
> +
> +  // Check that Infinity and NaN convert to a string that is interpreted as the same APFloat

Comments should be complete sentences (they should end with periods).

Also, all these lines violate the 80-column rule.  I'd recommend
integrating `clang-format` [1] into your workflow, since it will handle
formatting for you.

[1]: http://clang.llvm.org/docs/ClangFormat.html

> +  double posInf = APFloat::getInf(APFloat::IEEEdouble, false).convertToDouble();
> +  EXPECT_EQ(posInf, convertToDoubleFromString(convertToString(posInf, 0, 3).c_str()));

Current style guidelines say variables should start with a capital
letter, so this would be `PosInf`.

However, this is all pretty mechanical.  I think you should use a macro:

    #define EXPECT_ROUNDTRIP(F)                                                    \
      EXPECT_TRUE((F).bitwiseIsEqual(APFloat(                                      \
          APFloat::IEEEdouble, convertToString((F).convertToDouble(), 0, 0))))
      EXPECT_ROUNDTRIP(APFloat::getInf(APFloat::IEEEdouble, false));
      EXPECT_ROUNDTRIP(APFloat::getInf(APFloat::IEEEdouble, true));
      EXPECT_ROUNDTRIP(APFloat::getNaN(APFloat::IEEEdouble, false));
      EXPECT_ROUNDTRIP(APFloat::getNaN(APFloat::IEEEdouble, true));
    #undef EXPECT_ROUNDTRIP

A few more points:

  - As a prep patch, change `convertToDouble()` to take a `StringRef`.
  - These would be better in a new test (maybe called
    `TEST(APFloatTest, StringRoundtrip)`?).
  - You should add explicit checks for `convertToString()` here (after
    moving your new tests elsewhere).
  - You should add "from-string" tests somewhere to explicitly check
    whether we can parse these special numbers.

> +  double negInf = APFloat::getInf(APFloat::IEEEdouble, true).convertToDouble();
> +  EXPECT_EQ(negInf, convertToDoubleFromString(convertToString(negInf, 5, 2).c_str()));
> +  // NaN does not compare with itself (assert(posNaN != posNaN)), so do a bitwise compare instead
> +  APFloat posNaN = APFloat::getNaN(APFloat::IEEEdouble, false);
> +  EXPECT_TRUE(posNaN.bitwiseIsEqual( 
> +              APFloat(APFloat::IEEEdouble, convertToString(posNaN.convertToDouble(), 5, 0).c_str()) ));
> +  APFloat negNaN = APFloat::getNaN(APFloat::IEEEdouble, true);
> +  EXPECT_TRUE(negNaN.bitwiseIsEqual( 
> +              APFloat(APFloat::IEEEdouble, convertToString(negNaN.convertToDouble(), 3, 1).c_str()) ));
>  }
>  
>  TEST(APFloatTest, toInteger) {
> 





More information about the llvm-commits mailing list