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

Reply via email to