Date: Friday, January 27, 2006 @ 15:54:00
Author: marc
Path: /cvsroot/carob/carob
Modified: src/ParameterStatement.cpp (1.11 -> 1.12)
test/40-Parameter-PreparedStatement/TestIEEE754.cpp (1.6 -> 1.7)
test/40-Parameter-PreparedStatement/TestIEEE754.hpp (1.1 -> 1.2)
Implemented NaNs (and simplified infinity). Should be enough to close CAROB-31
(at last!).
-----------------------------------------------------+
src/ParameterStatement.cpp | 34 ++++++---
test/40-Parameter-PreparedStatement/TestIEEE754.cpp | 68 ++++++++++++++++--
test/40-Parameter-PreparedStatement/TestIEEE754.hpp | 1
3 files changed, 88 insertions(+), 15 deletions(-)
Index: carob/src/ParameterStatement.cpp
diff -u carob/src/ParameterStatement.cpp:1.11
carob/src/ParameterStatement.cpp:1.12
--- carob/src/ParameterStatement.cpp:1.11 Fri Jan 27 13:22:12 2006
+++ carob/src/ParameterStatement.cpp Fri Jan 27 15:54:00 2006
@@ -26,6 +26,10 @@
#include "Common.hpp"
#include "CarobException.hpp"
+#include <math.h> // C99 has isinf(), isnan(), etc.
+// #include <cmath> // and they are not available in C+98!
+
+
namespace CarobNS {
/**
* All tags must have the same length
@@ -230,18 +234,30 @@
public:
FPoneShotFilter(basic_ostream<wchar_t>& s) : wrapped_stream(s) { } ;
basic_ostream<wchar_t>&
- // this is the actual filtering operator
+
+ // This is the actual filtering operator
operator<< (FP value)
{
- // too bad Standard C and Java could not agree on the same string :-(
- if (value == std::numeric_limits<FP>::infinity())
- wrapped_stream << L"Infinity"; // see java.lang.(Float|Double)#toString()
- else if (value == -std::numeric_limits<FP>::infinity())
- wrapped_stream << L"-Infinity";
- // TODO: catch NaNs
- else
+ // Warning: this is C99 code, not C++98!
+
+ // first the common case
+ if (!isnan(value) && !isinf(value)) {
wrapped_stream << value;
- // then return the underlying stream (we filter only once!)
+ return wrapped_stream;
+ }
+
+ // now the exceptional cases
+ // Bug: java.lang.FloatingDecimal#readJavaFormatString()
+ // ignores negative sign of NaN
+ if (signbit(value))
+ wrapped_stream << L"-";
+
+ // Too bad Standard C99 and Java could not agree on the same strings :-(
+ if (isinf(value))
+ wrapped_stream << L"Infinity"; // see java.lang.(Float|Double)#toString()
+ else if (isnan(value)) // forget about quiet vs signaling
+ wrapped_stream << L"NaN";
+
return wrapped_stream;
}
};
Index: carob/test/40-Parameter-PreparedStatement/TestIEEE754.cpp
diff -u carob/test/40-Parameter-PreparedStatement/TestIEEE754.cpp:1.6
carob/test/40-Parameter-PreparedStatement/TestIEEE754.cpp:1.7
--- carob/test/40-Parameter-PreparedStatement/TestIEEE754.cpp:1.6 Thu Jan
26 00:18:52 2006
+++ carob/test/40-Parameter-PreparedStatement/TestIEEE754.cpp Fri Jan 27
15:54:00 2006
@@ -23,7 +23,9 @@
#include "ParameterStatement.hpp"
-#include <cmath>
+#include <math.h> // C99 has isinf(), isnan(), etc.
+// #include <cmath> // and they are not available in C+98
+
#include <limits>
// substitute here with the float32_t and float64_t types of your
@@ -40,6 +42,10 @@
#endif
+#include <iostream>
+
+using namespace CarobNS;
+
namespace {
typedef std::numeric_limits<float> Floats;
@@ -60,9 +66,36 @@
return 0;
}
+
+
+
+void
+printrow(float f, double d)
+{
+ std::cout.setf(std::ios_base::scientific, std::ios_base::floatfield);
+ std::cout.setf(std::ios_base::hex, std::ios_base::basefield);
+ std::cout.setf(std::ios_base::showbase | std::ios_base::internal);
+ std::cout.fill('0');
+
+ std::cout.precision(9);
+ std::cout << f << " (=";
+ std::cout.width(10);
+ std::cout << SQLDataSerialization::floatToU32Bits(f) << ") | ";
+ std::cout.precision(17);
+ std::cout << d << " (=";
+ std::cout.width(18);
+ std::cout << SQLDataSerialization::doubleToU64Bits(d) << ")";
+}
+
+template <class FP> bool
+better_equal(FP a, FP b)
+{
+ if (isnan(a))
+ return (isnan(b) && (signbit(a) == signbit(b)));
+ else
+ return (a == b);
}
-using namespace CarobNS;
void
write_read(Connection * conn, const fd_t data[])
@@ -95,12 +128,23 @@
while (data[row].f || data[row].d) {
CPPUNIT_ASSERT(drsPtr->next());
CPPUNIT_ASSERT(drsPtr->getAsInt(1) == row);
- CPPUNIT_ASSERT(drsPtr->getAsFloat(2) == data[row].f);
- CPPUNIT_ASSERT(drsPtr->getDouble(3) == data[row].d);
+
+#define DEBUGIT 0
+#if DEBUGIT
+ std::cout << "tried to send: ";
+ printrow(data[row].f, data[row].d);
+ std::cout << std::endl << "received: ";
+ printrow(drsPtr->getAsFloat(2), drsPtr->getDouble(3));
+ std::cout << std::endl;
+#else // assert it
+ CPPUNIT_ASSERT(better_equal(drsPtr->getAsFloat(2), data[row].f));
+ CPPUNIT_ASSERT(better_equal(drsPtr->getDouble(3), data[row].d));
+#endif
row++;
}
}
+} // unnamed namespace
void
@@ -139,8 +183,20 @@
fd_t basicdata[] =
{
-// { Floats::infinity(), -Doubles::infinity() },
- { 0, 0 } // END OF DATA
+ { Floats::infinity(), -Doubles::infinity() },
+
+ // No one seems to make the difference between quiet vs signaling
+ { Floats::quiet_NaN(), Doubles::quiet_NaN() },
+ { Floats::signaling_NaN(), Doubles::signaling_NaN() },
+
+ // disabled cause java.lang.FloatingDecimal#readJavaFormatString()
+ // ignores negative sign of NaN
+#if 0
+ { -Floats::quiet_NaN(), -Doubles::quiet_NaN() },
+ { -Floats::signaling_NaN(), -Doubles::signaling_NaN() },
+#endif
+
+ { 0, 0 } // END OF DATA
};
write_read(connectionPtr, basicdata);
Index: carob/test/40-Parameter-PreparedStatement/TestIEEE754.hpp
diff -u carob/test/40-Parameter-PreparedStatement/TestIEEE754.hpp:1.1
carob/test/40-Parameter-PreparedStatement/TestIEEE754.hpp:1.2
--- carob/test/40-Parameter-PreparedStatement/TestIEEE754.hpp:1.1 Fri Jan
20 23:44:50 2006
+++ carob/test/40-Parameter-PreparedStatement/TestIEEE754.hpp Fri Jan 27
15:54:00 2006
@@ -22,6 +22,7 @@
#include "../ConnectionSetup.hpp"
+#include "SQLDataSerialization.hpp"
/**
* Test for IEEE754 double and floats
_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits