aboutsummaryrefslogtreecommitdiff
path: root/lib/Support/APFloat.cpp
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2009-01-20 18:35:05 +0000
committerDale Johannesen <dalej@apple.com>2009-01-20 18:35:05 +0000
commit24b66a83ca8c80417ad7523c35ece709a7e6599c (patch)
treee28d31de0e903db3af95b00dd238593784d55bb8 /lib/Support/APFloat.cpp
parentccb3ab46f62504a84b3fda435e282821dea55438 (diff)
Add an IEEE remainder function, which is not
fully implemented yet and not used. This is mainly to clarify that APFloat::mod implements C fmod, not remainder. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62593 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/APFloat.cpp')
-rw-r--r--lib/Support/APFloat.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index fde157d60f..151f9d5b39 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -1514,7 +1514,45 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
return fs;
}
-/* Normalized remainder. This is not currently doing TRT. */
+/* Normalized remainder. This is not currently correct in all cases. */
+APFloat::opStatus
+APFloat::remainder(const APFloat &rhs)
+{
+ opStatus fs;
+ APFloat V = *this;
+ unsigned int origSign = sign;
+
+ assertArithmeticOK(*semantics);
+ fs = V.divide(rhs, rmNearestTiesToEven);
+ if (fs == opDivByZero)
+ return fs;
+
+ int parts = partCount();
+ integerPart *x = new integerPart[parts];
+ bool ignored;
+ fs = V.convertToInteger(x, parts * integerPartWidth, true,
+ rmNearestTiesToEven, &ignored);
+ if (fs==opInvalidOp)
+ return fs;
+
+ fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true,
+ rmNearestTiesToEven);
+ assert(fs==opOK); // should always work
+
+ fs = V.multiply(rhs, rmNearestTiesToEven);
+ assert(fs==opOK || fs==opInexact); // should not overflow or underflow
+
+ fs = subtract(V, rmNearestTiesToEven);
+ assert(fs==opOK || fs==opInexact); // likewise
+
+ if (isZero())
+ sign = origSign; // IEEE754 requires this
+ delete[] x;
+ return fs;
+}
+
+/* Normalized llvm frem (C fmod).
+ This is not currently correct in all cases. */
APFloat::opStatus
APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
{