dbertoni 00/04/20 09:27:45
Modified: c/src/XPath FunctionRound.hpp
Log:
Handle special values (NaN, etc.), and some other special cases correctly.
Revision Changes Path
1.5 +50 -5 xml-xalan/c/src/XPath/FunctionRound.hpp
Index: FunctionRound.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/FunctionRound.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- FunctionRound.hpp 2000/04/11 14:46:07 1.4
+++ FunctionRound.hpp 2000/04/20 16:27:45 1.5
@@ -64,16 +64,20 @@
+#include <cmath>
#include <vector>
// Base class header file...
-// Base class header file...
#include <XPath/Function.hpp>
+#include <PlatformSupport/DoubleSupport.hpp>
+
+
+
#include <XPath/XObject.hpp>
#include <XPath/XObjectFactory.hpp>
#include <XPath/XPathExecutionContext.hpp>
@@ -107,11 +111,8 @@
}
const double theValue = args[0]->num();
-
- // $$$ ToDo: This is not really correct, but will do for now...
- const long theRoundedValue = static_cast<long>(theValue <
0 ? theValue - 0.5 : theValue + 0.5);
- return
executionContext.getXObjectFactory().createNumber(theRoundedValue);
+ return
executionContext.getXObjectFactory().createNumber(getRoundedValue(theValue));
}
#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
@@ -122,6 +123,50 @@
clone() const
{
return new FunctionRound(*this);
+ }
+
+ static double
+ getRoundedValue(double theValue)
+ {
+ if (DoubleSupport::isNaN(theValue))
+ {
+ return DoubleSupport::getNaN();
+ }
+ else if (DoubleSupport::isPositiveInfinity(theValue))
+ {
+ return DoubleSupport::getPositiveInfinity();
+ }
+ if (DoubleSupport::isNegativeInfinity(theValue))
+ {
+ return DoubleSupport::getNegativeInfinity();
+ }
+ else if (theValue == 0)
+ {
+ return 0.0;
+ }
+ else if (theValue > 0)
+ {
+ return static_cast<long>(theValue + 0.5);
+ }
+ else
+ {
+ // Negative numbers are a special case. Any time we
+ // have -0.5 as the fractional part, we have to
+ // round up (toward 0), rather than down.
+ double intPart = 0;
+
+ const double fracPart = modf(theValue, &intPart);
+
+ if (fracPart == -0.5)
+ {
+ // special case -- we have have to round toward
0...
+ return static_cast<long>(theValue + 0.5);
+ }
+ else
+ {
+ return static_cast<long>(theValue - 0.5);
+ }
+ }
}
private: