THRIFT-3376 C# and Python JSON protocol double values lose precision
Client: C#, Python, C++, Ruby
Patch: Nobuaki Sukegawa <nsukeg@gmail.com>
This closes #643
diff --git a/test/cpp/src/TestClient.cpp b/test/cpp/src/TestClient.cpp
index 1ab4d21..2736ee8 100644
--- a/test/cpp/src/TestClient.cpp
+++ b/test/cpp/src/TestClient.cpp
@@ -106,6 +106,29 @@
}
}
+// Workaround for absense of C++11 "auto" keyword.
+template <typename T>
+bool print_eq(T expected, T actual) {
+ cout << "(" << actual << ")" << endl;
+ if (expected != actual) {
+ cout << "*** FAILED ***" << endl << "Expected: " << expected << " but got: " << actual << endl;
+ return false;
+ }
+ return true;
+}
+
+#define BASETYPE_IDENTITY_TEST(func, value) \
+ cout << #func "(" << value << ") = "; \
+ try { \
+ if (!print_eq(value, testClient.func(value))) \
+ return_code |= ERR_BASETYPES; \
+ } catch (TTransportException&) { \
+ throw; \
+ } catch (exception & ex) { \
+ cout << "*** FAILED ***" << endl << ex.what() << endl; \
+ return_code |= ERR_BASETYPES; \
+ }
+
int main(int argc, char** argv) {
int ERR_BASETYPES = 1;
int ERR_STRUCTS = 2;
@@ -388,11 +411,47 @@
/**
* DOUBLE TEST
*/
- printf("testDouble(-5.2098523)");
- double dub = testClient.testDouble(-5.2098523);
- printf(" = %f\n", dub);
- if ((dub - (-5.2098523)) > 0.001) {
- printf("*** FAILED ***\n");
+ // Comparing double values with plain equality because Thrift handles full precision of double
+ BASETYPE_IDENTITY_TEST(testDouble, 0.0);
+ BASETYPE_IDENTITY_TEST(testDouble, -1.0);
+ BASETYPE_IDENTITY_TEST(testDouble, -5.2098523);
+ BASETYPE_IDENTITY_TEST(testDouble, -0.000341012439638598279);
+ BASETYPE_IDENTITY_TEST(testDouble, pow(2, 32));
+ BASETYPE_IDENTITY_TEST(testDouble, pow(2, 32) + 1);
+ BASETYPE_IDENTITY_TEST(testDouble, pow(2, 53) - 1);
+ BASETYPE_IDENTITY_TEST(testDouble, -pow(2, 32));
+ BASETYPE_IDENTITY_TEST(testDouble, -pow(2, 32) - 1);
+ BASETYPE_IDENTITY_TEST(testDouble, -pow(2, 53) + 1);
+
+ try {
+ double expected = pow(10, 307);
+ cout << "testDouble(" << expected << ") = ";
+ double actual = testClient.testDouble(expected);
+ cout << "(" << actual << ")" << endl;
+ if (expected - actual > pow(10, 292)) {
+ cout << "*** FAILED ***" << endl
+ << "Expected: " << expected << " but got: " << actual << endl;
+ }
+ } catch (TTransportException&) {
+ throw;
+ } catch (exception& ex) {
+ cout << "*** FAILED ***" << endl << ex.what() << endl;
+ return_code |= ERR_BASETYPES;
+ }
+
+ try {
+ double expected = pow(10, -292);
+ cout << "testDouble(" << expected << ") = ";
+ double actual = testClient.testDouble(expected);
+ cout << "(" << actual << ")" << endl;
+ if (expected - actual > pow(10, -307)) {
+ cout << "*** FAILED ***" << endl
+ << "Expected: " << expected << " but got: " << actual << endl;
+ }
+ } catch (TTransportException&) {
+ throw;
+ } catch (exception& ex) {
+ cout << "*** FAILED ***" << endl << ex.what() << endl;
return_code |= ERR_BASETYPES;
}