summaryrefslogtreecommitdiff
path: root/sc/inc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-08-13 22:03:53 +0200
committerEike Rathke <erack@redhat.com>2015-08-13 22:43:57 +0200
commitd0d76a9aad90c8f07330da7f67eef5c607a27aec (patch)
treefce0ce302a06147de35e8ff8149b787be2961d67 /sc/inc
parent6609b05765e674f2f4694854097a5318b617fd54 (diff)
add sc::divide() for defined -fsanitize=float-divide-by-zero behavior
Change-Id: I3af85344119ca0056a127a5278e8993f9d79e2f9
Diffstat (limited to 'sc/inc')
-rw-r--r--sc/inc/math.hxx29
1 files changed, 29 insertions, 0 deletions
diff --git a/sc/inc/math.hxx b/sc/inc/math.hxx
index 8a95f219d8fd..46f9a1d30fca 100644
--- a/sc/inc/math.hxx
+++ b/sc/inc/math.hxx
@@ -24,12 +24,41 @@
namespace sc {
+/** Return fNumerator/fDenominator if fDenominator!=0 else #DIV/0! error coded
+ into double.
+ */
inline double div( const double& fNumerator, const double& fDenominator )
{
return (fDenominator != 0.0) ? (fNumerator / fDenominator) :
CreateDoubleError( errDivisionByZero);
}
+/** Return fNumerator/fDenominator if fDenominator!=0 else +-Infinity if
+ fNumerator!=0 or NaN if fNumerator==0.
+
+ This allows to build/run with -fsanitize=float-divide-by-zero and have a
+ defined behavior for the otherwise undefined division by zero case ("If the
+ second operand of / or % is zero the behavior is undefined."
+ ([expr.mul]/4)).
+
+ The Calc interpreter gracefully handles Infinity or NaN double values
+ encountered as interim or final results, using this function we can ensure
+ defined behavior where desired.
+
+ Use where the double coded error creating div() is not wanted.
+ */
+inline double divide( const double& fNumerator, const double& fDenominator )
+{
+ if (fDenominator == 0.0) {
+ if (std::isfinite(fNumerator) && fNumerator != 0.0) {
+ return std::copysign(INFINITY, fNumerator);
+ } else {
+ return NAN;
+ }
+ }
+ return fNumerator / fDenominator;
+}
+
}
#endif