llvm.org GIT mirror llvm / f7a5dfc
Fix a problem with APFloat::roundToIntegral where it would return incorrect results for negative inputs to trunc. Add unit tests to verify this behavior. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161929 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 8 years ago
2 changed file(s) with 42 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
17731773 // precision of our format, and then subtract it back off again. The choice
17741774 // of rounding modes for the addition/subtraction determines the rounding mode
17751775 // for our integral rounding as well.
1776 // NOTE: When the input value is negative, we do subtractation followed by
1777 // addition instead.
17761778 APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1);
17771779 IntegerConstant <<= semanticsPrecision(*semantics)-1;
17781780 APFloat MagicConstant(*semantics);
17791781 fs = MagicConstant.convertFromAPInt(IntegerConstant, false,
17801782 rmNearestTiesToEven);
1783 MagicConstant.copySign(*this);
1784
17811785 if (fs != opOK)
17821786 return fs;
1787
1788 // Preserve the input sign so that we can handle 0.0/-0.0 cases correctly.
1789 bool inputSign = isNegative();
17831790
17841791 fs = add(MagicConstant, rounding_mode);
17851792 if (fs != opOK && fs != opInexact)
17861793 return fs;
17871794
17881795 fs = subtract(MagicConstant, rounding_mode);
1796
1797 // Restore the input sign.
1798 if (inputSign != isNegative())
1799 changeSign();
1800
17891801 return fs;
17901802 }
17911803
647647 EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0));
648648 }
649649
650 TEST(APFloatTest, roundToIntegral) {
651 APFloat T(-0.5), S(3.14), P(0.0);
652
653 P = T;
654 P.roundToIntegral(APFloat::rmTowardZero);
655 EXPECT_EQ(-0.0, P.convertToDouble());
656 P = T;
657 P.roundToIntegral(APFloat::rmTowardNegative);
658 EXPECT_EQ(-1.0, P.convertToDouble());
659 P = T;
660 P.roundToIntegral(APFloat::rmTowardPositive);
661 EXPECT_EQ(-0.0, P.convertToDouble());
662 P = T;
663 P.roundToIntegral(APFloat::rmNearestTiesToEven);
664 EXPECT_EQ(-0.0, P.convertToDouble());
665
666 P = S;
667 P.roundToIntegral(APFloat::rmTowardZero);
668 EXPECT_EQ(3.0, P.convertToDouble());
669 P = S;
670 P.roundToIntegral(APFloat::rmTowardNegative);
671 EXPECT_EQ(3.0, P.convertToDouble());
672 P = S;
673 P.roundToIntegral(APFloat::rmTowardPositive);
674 EXPECT_EQ(4.0, P.convertToDouble());
675 P = S;
676 P.roundToIntegral(APFloat::rmNearestTiesToEven);
677 EXPECT_EQ(3.0, P.convertToDouble());
678 }
679
650680 TEST(APFloatTest, getLargest) {
651681 EXPECT_EQ(3.402823466e+38f, APFloat::getLargest(APFloat::IEEEsingle).convertToFloat());
652682 EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble).convertToDouble());