/* Assumed in hexadecimal significand parsing, and conversion to
hexadecimal strings. */
-#define COMPILE_TIME_ASSERT(cond) extern int CTAssert[(cond) ? 1 : -1]
-COMPILE_TIME_ASSERT(integerPartWidth % 4 == 0);
+static_assert(integerPartWidth % 4 == 0, "Part width must be divisible by 4!");
namespace llvm {
{
StringRef::iterator p = begin;
*dot = end;
- while (*p == '0' && p != end)
+ while (p != end && *p == '0')
p++;
- if (*p == '.') {
+ if (p != end && *p == '.') {
*dot = p++;
assert(end - begin != 1 && "Significand has no digits");
- while (*p == '0' && p != end)
+ while (p != end && *p == '0')
p++;
}
return *this;
}
+APFloat &
+APFloat::operator=(APFloat &&rhs) {
+ freeSignificand();
+
+ semantics = rhs.semantics;
+ significand = rhs.significand;
+ exponent = rhs.exponent;
+ category = rhs.category;
+ sign = rhs.sign;
+
+ rhs.semantics = &Bogus;
+ return *this;
+}
+
bool
APFloat::isDenormal() const {
return isFiniteNonZero() && (exponent == semantics->minExponent) &&
APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
initialize(&ourSemantics);
sign = 0;
+ category = fcNormal;
zeroSignificand();
exponent = ourSemantics.precision - 1;
significandParts()[0] = value;
assign(rhs);
}
+APFloat::APFloat(APFloat &&rhs) : semantics(&Bogus) {
+ *this = std::move(rhs);
+}
+
APFloat::~APFloat()
{
freeSignificand();
void
APFloat::zeroSignificand()
{
- category = fcNormal;
APInt::tcSet(significandParts(), 0, partCount());
}
// exponent accordingly.
exponent += 1;
- if (addend) {
+ if (addend && addend->isNonZero()) {
// The intermediate result of the multiplication has "2 * precision"
// signicant bit; adjust the addend to be consistent with mul result.
//
{
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
case PackCategoriesIntoKey(fcNaN, fcZero):
case PackCategoriesIntoKey(fcNaN, fcNormal):
case PackCategoriesIntoKey(fcZero, fcNaN):
case PackCategoriesIntoKey(fcNormal, fcNaN):
case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ // We need to be sure to flip the sign here for subtraction because we
+ // don't have a separate negate operation so -NaN becomes 0 - NaN here.
+ sign = rhs.sign ^ subtract;
category = fcNaN;
copySignificand(rhs);
return opOK;
{
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
case PackCategoriesIntoKey(fcNaN, fcZero):
case PackCategoriesIntoKey(fcNaN, fcNormal):
case PackCategoriesIntoKey(fcNaN, fcInfinity):
case PackCategoriesIntoKey(fcNaN, fcNaN):
+ sign = false;
return opOK;
case PackCategoriesIntoKey(fcZero, fcNaN):
case PackCategoriesIntoKey(fcNormal, fcNaN):
case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ sign = false;
category = fcNaN;
copySignificand(rhs);
return opOK;
{
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ category = fcNaN;
+ copySignificand(rhs);
case PackCategoriesIntoKey(fcNaN, fcZero):
case PackCategoriesIntoKey(fcNaN, fcNormal):
case PackCategoriesIntoKey(fcNaN, fcInfinity):
case PackCategoriesIntoKey(fcNaN, fcNaN):
+ sign = false;
case PackCategoriesIntoKey(fcInfinity, fcZero):
case PackCategoriesIntoKey(fcInfinity, fcNormal):
case PackCategoriesIntoKey(fcZero, fcInfinity):
case PackCategoriesIntoKey(fcZero, fcNormal):
return opOK;
- case PackCategoriesIntoKey(fcZero, fcNaN):
- case PackCategoriesIntoKey(fcNormal, fcNaN):
- case PackCategoriesIntoKey(fcInfinity, fcNaN):
- category = fcNaN;
- copySignificand(rhs);
- return opOK;
-
case PackCategoriesIntoKey(fcNormal, fcInfinity):
category = fcZero;
return opOK;
{
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
case PackCategoriesIntoKey(fcNaN, fcZero):
case PackCategoriesIntoKey(fcNaN, fcNormal):
case PackCategoriesIntoKey(fcZero, fcNaN):
case PackCategoriesIntoKey(fcNormal, fcNaN):
case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ sign = false;
category = fcNaN;
copySignificand(rhs);
return opOK;
fs = multiplySpecials(rhs);
if (isFiniteNonZero()) {
- lostFraction lost_fraction = multiplySignificand(rhs, 0);
+ lostFraction lost_fraction = multiplySignificand(rhs, nullptr);
fs = normalize(rounding_mode, lost_fraction);
if (lost_fraction != lfExactlyZero)
fs = (opStatus) (fs | opInexact);
extended-precision calculation. */
if (isFiniteNonZero() &&
multiplicand.isFiniteNonZero() &&
- addend.isFiniteNonZero()) {
+ addend.isFinite()) {
lostFraction lost_fraction;
lost_fraction = multiplySignificand(multiplicand, &addend);
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
case PackCategoriesIntoKey(fcNaN, fcZero):
case PackCategoriesIntoKey(fcNaN, fcNormal):
{
lostFraction lost_fraction = lfExactlyZero;
+ category = fcNormal;
zeroSignificand();
exponent = 0;
- category = fcNormal;
integerPart *significand = significandParts();
unsigned partsCount = partCount();
if (exp >= 0) {
/* multiplySignificand leaves the precision-th bit set to 1. */
- calcLostFraction = decSig.multiplySignificand(pow5, NULL);
+ calcLostFraction = decSig.multiplySignificand(pow5, nullptr);
powHUerr = powStatus != opOK;
} else {
calcLostFraction = decSig.divideSignificand(pow5);
(D.normalizedExponent + 1) * 28738 <=
8651 * (semantics->minExponent - (int) semantics->precision)) {
/* Underflow to zero and round. */
+ category = fcNormal;
zeroSignificand();
fs = normalize(rounding_mode, lfLessThanHalf);
if (Sem == &PPCDoubleDouble)
return initFromPPCDoubleDoubleAPInt(api);
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
APFloat
// internal consistency.
const unsigned NumUnusedHighBits =
PartCount*integerPartWidth - semantics->precision;
- significand[PartCount - 1] = ~integerPart(0) >> NumUnusedHighBits;
+ significand[PartCount - 1] = (NumUnusedHighBits < integerPartWidth)
+ ? (~integerPart(0) >> NumUnusedHighBits)
+ : 0;
}
/// Make this number the smallest magnitude denormal number in the given
// exponent = 0..0
// significand = 10..0
+ Val.category = fcNormal;
Val.zeroSignificand();
Val.sign = Negative;
Val.exponent = Sem.minExponent;
// 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.
+ // We use enough digits so the number can be round-tripped back to an
+ // APFloat. The formula comes from "How to Print Floating-Point Numbers
+ // Accurately" by Steele and White.
+ // FIXME: Using a formula based purely on the precision is conservative;
+ // we can print fewer digits depending on the actual value being printed.
- // FormatPrecision = ceil(significandBits / lg_2(10))
- FormatPrecision = (semantics->precision * 59 + 195) / 196;
+ // FormatPrecision = 2 + floor(significandBits / lg_2(10))
+ FormatPrecision = 2 + semantics->precision * 59 / 196;
}
// Ignore trailing binary zeros.
// change the payload.
if (isSignaling()) {
result = opInvalidOp;
- // For consistency, propogate the sign of the sNaN to the qNaN.
- makeNaN(false, isNegative(), 0);
+ // For consistency, propagate the sign of the sNaN to the qNaN.
+ makeNaN(false, isNegative(), nullptr);
}
break;
case fcZero:
// Decrement the significand.
//
// We always do this since:
- // 1. If we are dealing with a non binade decrement, by definition we
+ // 1. If we are dealing with a non-binade decrement, by definition we
// just decrement the significand.
// 2. If we are dealing with a normal -> normal binade decrement, since
// we have an explicit integral bit the fact that all bits but the
exponent = semantics->minExponent-1;
APInt::tcSet(significandParts(), 0, partCount());
}
+
+APFloat llvm::scalbn(APFloat X, int Exp) {
+ if (X.isInfinity() || X.isZero() || X.isNaN())
+ return std::move(X);
+
+ auto MaxExp = X.getSemantics().maxExponent;
+ auto MinExp = X.getSemantics().minExponent;
+ if (Exp > (MaxExp - X.exponent))
+ // Overflow saturates to infinity.
+ return APFloat::getInf(X.getSemantics(), X.isNegative());
+ if (Exp < (MinExp - X.exponent))
+ // Underflow saturates to zero.
+ return APFloat::getZero(X.getSemantics(), X.isNegative());
+
+ X.exponent += Exp;
+ return std::move(X);
+}