llvm.org GIT mirror llvm / 3d42bfb
Add an APFloat::convertToInt(APSInt) function that automatically manages the memory for the result. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135259 91177308-0d34-0410-b5e6-96231b3b80d8 Jeffrey Yasskin 9 years ago
3 changed file(s) with 69 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
108108 typedef signed short exponent_t;
109109
110110 struct fltSemantics;
111 class APSInt;
111112 class StringRef;
112113
113114 /* When bits of a floating point number are truncated, this enum is
282283 opStatus convert(const fltSemantics &, roundingMode, bool *);
283284 opStatus convertToInteger(integerPart *, unsigned int, bool,
284285 roundingMode, bool *) const;
286 opStatus convertToInteger(APSInt&, roundingMode, bool *) const;
285287 opStatus convertFromAPInt(const APInt &,
286288 bool, roundingMode);
287289 opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
1212 //===----------------------------------------------------------------------===//
1313
1414 #include "llvm/ADT/APFloat.h"
15 #include "llvm/ADT/APSInt.h"
1516 #include "llvm/ADT/StringRef.h"
1617 #include "llvm/ADT/FoldingSet.h"
1718 #include "llvm/Support/ErrorHandling.h"
20832084 return fs;
20842085 }
20852086
2087 /* Same as convertToInteger(integerPart*, ...), except the result is returned in
2088 an APSInt, whose initial bit-width and signed-ness are used to determine the
2089 precision of the conversion.
2090 */
2091 APFloat::opStatus
2092 APFloat::convertToInteger(APSInt &result,
2093 roundingMode rounding_mode, bool *isExact) const
2094 {
2095 unsigned bitWidth = result.getBitWidth();
2096 SmallVector parts(result.getNumWords());
2097 opStatus status = convertToInteger(
2098 parts.data(), bitWidth, result.isSigned(), rounding_mode, isExact);
2099 // Keeps the original signed-ness.
2100 result = APInt(bitWidth, parts.size(), parts.data());
2101 return status;
2102 }
2103
20862104 /* Convert an unsigned integer SRC to a floating point number,
20872105 rounding according to ROUNDING_MODE. The sign of the floating
20882106 point number is not modified. */
1111 #include "llvm/Support/raw_ostream.h"
1212 #include "gtest/gtest.h"
1313 #include "llvm/ADT/APFloat.h"
14 #include "llvm/ADT/APSInt.h"
1415 #include "llvm/ADT/SmallString.h"
1516 #include "llvm/ADT/SmallVector.h"
1617
343344 ASSERT_EQ("8.731834E+2", convertToString(873.1834, 0, 0));
344345 }
345346
347 TEST(APFloatTest, toInteger) {
348 bool isExact = false;
349 APSInt result(5, /*isUnsigned=*/true);
350
351 EXPECT_EQ(APFloat::opOK,
352 APFloat(APFloat::IEEEdouble, "10")
353 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
354 EXPECT_TRUE(isExact);
355 EXPECT_EQ(APSInt(APInt(5, 10), true), result);
356
357 EXPECT_EQ(APFloat::opInvalidOp,
358 APFloat(APFloat::IEEEdouble, "-10")
359 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
360 EXPECT_FALSE(isExact);
361 EXPECT_EQ(APSInt::getMinValue(5, true), result);
362
363 EXPECT_EQ(APFloat::opInvalidOp,
364 APFloat(APFloat::IEEEdouble, "32")
365 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
366 EXPECT_FALSE(isExact);
367 EXPECT_EQ(APSInt::getMaxValue(5, true), result);
368
369 EXPECT_EQ(APFloat::opInexact,
370 APFloat(APFloat::IEEEdouble, "7.9")
371 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
372 EXPECT_FALSE(isExact);
373 EXPECT_EQ(APSInt(APInt(5, 7), true), result);
374
375 result.setIsUnsigned(false);
376 EXPECT_EQ(APFloat::opOK,
377 APFloat(APFloat::IEEEdouble, "-10")
378 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
379 EXPECT_TRUE(isExact);
380 EXPECT_EQ(APSInt(APInt(5, -10, true), false), result);
381
382 EXPECT_EQ(APFloat::opInvalidOp,
383 APFloat(APFloat::IEEEdouble, "-17")
384 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
385 EXPECT_FALSE(isExact);
386 EXPECT_EQ(APSInt::getMinValue(5, false), result);
387
388 EXPECT_EQ(APFloat::opInvalidOp,
389 APFloat(APFloat::IEEEdouble, "16")
390 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
391 EXPECT_FALSE(isExact);
392 EXPECT_EQ(APSInt::getMaxValue(5, false), result);
393 }
394
346395 static APInt nanbits(const fltSemantics &Sem,
347396 bool SNaN, bool Negative, uint64_t fill) {
348397 APInt apfill(64, fill);