THRIFT-4476: Typecasting problem on double list items,
emitting doubles with high precision
Client: cpp
Client: erl
Client: java
Client: js
Client: py

This closes #1511
diff --git a/appveyor.yml b/appveyor.yml
index 26bfcfb..121fe1c 100755
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -107,5 +107,4 @@
 #
 # also need:
 # environment:
-#   APPVEYOR_RDP_PASSWORD: thr1FT2345$xyzZ
-
+#   APPVEYOR_RDP_PASSWORD: thr1FT2345$xyzZ
\ No newline at end of file
diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
index 08e2c97..c78b806 100644
--- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
@@ -24,7 +24,9 @@
 #include <cassert>
 
 #include <fstream>
+#include <iomanip>
 #include <iostream>
+#include <limits>
 #include <sstream>
 #include <string>
 #include <vector>
@@ -788,9 +790,9 @@
       break;
     case t_base_type::TYPE_DOUBLE:
       if (value->get_type() == t_const_value::CV_INTEGER) {
-        render << value->get_integer();
+        render << "static_cast<double>(" << value->get_integer() << ")";
       } else {
-        render << value->get_double();
+        render << emit_double_as_string(value->get_double());
       }
       break;
     default:
diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
index 4ddcf68..768db13 100644
--- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
@@ -384,6 +384,36 @@
   f_consts_hrl_file_.close();
 }
 
+const std::string emit_double_as_string(const double value) {
+  std::stringstream double_output_stream;
+  // sets the maximum precision: http://en.cppreference.com/w/cpp/io/manip/setprecision
+  // sets the output format to fixed: http://en.cppreference.com/w/cpp/io/manip/fixed (not in scientific notation)
+  double_output_stream << std::setprecision(std::numeric_limits<double>::digits10 + 1);
+
+  #ifdef _MSC_VER
+      // strtod is broken in MSVC compilers older than 2015, so std::fixed fails to format a double literal.
+      // more details: https://blogs.msdn.microsoft.com/vcblog/2014/06/18/
+      //               c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
+      //               and
+      //               http://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
+      #if _MSC_VER >= MSC_2015_VER
+          double_output_stream << std::fixed;
+      #else
+          // note that if this function is called from the erlang generator and the MSVC compiler is older than 2015,
+          // the double literal must be output in the scientific format. There can be some cases where the
+          // mantissa of the output does not have fractionals, which is illegal in Erlang.
+          // example => 10000000000000000.0 being output as 1e+16
+          double_output_stream << std::scientific;
+      #endif
+  #else
+      double_output_stream << std::fixed;
+  #endif
+
+  double_output_stream << value;
+
+  return double_output_stream.str();
+}
+
 void t_erl_generator::generate_type_metadata(std::string function_name, vector<string> names) {
   vector<string>::iterator s_iter;
   size_t num_structs = names.size();
@@ -575,9 +605,9 @@
       break;
     case t_base_type::TYPE_DOUBLE:
       if (value->get_type() == t_const_value::CV_INTEGER) {
-        out << value->get_integer();
+        out << "float(" << value->get_integer() << ")";
       } else {
-        out << value->get_double();
+        out << emit_double_as_string(value->get_double());
       }
       break;
     default:
diff --git a/compiler/cpp/src/thrift/generate/t_generator.h b/compiler/cpp/src/thrift/generate/t_generator.h
index fc3f323..cbbfcb9 100644
--- a/compiler/cpp/src/thrift/generate/t_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_generator.h
@@ -19,10 +19,13 @@
 
 #ifndef T_GENERATOR_H
 #define T_GENERATOR_H
+#define MSC_2015_VER 1900
 
 #include <string>
+#include <iomanip>
 #include <iostream>
 #include <fstream>
+#include <limits>
 #include <sstream>
 #include "thrift/common.h"
 #include "thrift/version.h"
@@ -93,7 +96,7 @@
 
 protected:
   /**
-   * Optional methods that may be imlemented by subclasses to take necessary
+   * Optional methods that may be implemented by subclasses to take necessary
    * steps at the beginning or end of code generation.
    */
 
@@ -268,6 +271,30 @@
     return out.str();
   }
 
+  const std::string emit_double_as_string(const double value) {
+      std::stringstream double_output_stream;
+      // sets the maximum precision: http://en.cppreference.com/w/cpp/io/manip/setprecision
+      // sets the output format to fixed: http://en.cppreference.com/w/cpp/io/manip/fixed (not in scientific notation)
+      double_output_stream << std::setprecision(std::numeric_limits<double>::digits10 + 1);
+
+      #ifdef _MSC_VER
+          // strtod is broken in MSVC compilers older than 2015, so std::fixed fails to format a double literal.
+          // more details: https://blogs.msdn.microsoft.com/vcblog/2014/06/18/
+          //               c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
+          //               and
+          //               http://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
+          #if _MSC_VER >= MSC_2015_VER
+              double_output_stream << std::fixed;
+          #endif
+      #else
+          double_output_stream << std::fixed;
+      #endif
+
+      double_output_stream << value;
+
+      return double_output_stream.str();
+  }
+
 public:
   /**
    * Get the true type behind a series of typedefs.
diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc
index 2365242..3c7b753 100644
--- a/compiler/cpp/src/thrift/generate/t_java_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc
@@ -25,6 +25,7 @@
 #include <fstream>
 #include <iomanip>
 #include <iostream>
+#include <limits>
 #include <vector>
 #include <cctype>
 
@@ -734,9 +735,9 @@
       break;
     case t_base_type::TYPE_DOUBLE:
       if (value->get_type() == t_const_value::CV_INTEGER) {
-        render << "(double)" << value->get_integer();
+        render << value->get_integer() << "d";
       } else {
-        render << value->get_double();
+        render << emit_double_as_string(value->get_double());
       }
       break;
     default:
diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc
index da68cb5..7d160b9 100644
--- a/compiler/cpp/src/thrift/generate/t_js_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc
@@ -20,7 +20,9 @@
 #include <map>
 #include <string>
 #include <fstream>
+#include <iomanip>
 #include <iostream>
+#include <limits>
 #include <vector>
 #include <list>
 #include <cassert>
@@ -564,7 +566,7 @@
       if (value->get_type() == t_const_value::CV_INTEGER) {
         out << value->get_integer();
       } else {
-        out << value->get_double();
+        out << emit_double_as_string(value->get_double());
       }
       break;
     default:
diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc
index ab0227c..caa04a8 100644
--- a/compiler/cpp/src/thrift/generate/t_py_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc
@@ -19,7 +19,9 @@
 
 #include <string>
 #include <fstream>
+#include <iomanip>
 #include <iostream>
+#include <limits>
 #include <vector>
 
 #include <stdlib.h>
@@ -541,9 +543,9 @@
       break;
     case t_base_type::TYPE_DOUBLE:
       if (value->get_type() == t_const_value::CV_INTEGER) {
-        out << value->get_integer();
+        out << "float(" << value->get_integer() << ")";
       } else {
-        out << value->get_double();
+        out << emit_double_as_string(value->get_double());
       }
       break;
     default:
diff --git a/lib/cpp/test/Makefile.am b/lib/cpp/test/Makefile.am
index 587e2be..4b9f77d 100755
--- a/lib/cpp/test/Makefile.am
+++ b/lib/cpp/test/Makefile.am
@@ -39,6 +39,8 @@
 	gen-cpp/AnnotationTest_types.h \
 	gen-cpp/DebugProtoTest_types.cpp \
 	gen-cpp/DebugProtoTest_types.h \
+	gen-cpp/DoubleConstantsTest_constants.cpp \
+	gen-cpp/DoubleConstantsTest_constants.h \
 	gen-cpp/EnumTest_types.cpp \
 	gen-cpp/EnumTest_types.h \
 	gen-cpp/OptionalRequiredTest_types.cpp \
@@ -102,6 +104,7 @@
 	link_test \
 	OpenSSLManualInitTest \
 	EnumTest \
+	RenderedDoubleConstantsTest \
         AnnotationTest
 
 if AMX_HAVE_LIBEVENT
@@ -202,6 +205,10 @@
   libtestgencpp.la \
   $(BOOST_TEST_LDADD)
 
+RenderedDoubleConstantsTest_SOURCES = RenderedDoubleConstantsTest.cpp
+
+RenderedDoubleConstantsTest_LDADD = libtestgencpp.la $(BOOST_TEST_LDADD)
+
 AnnotationTest_SOURCES = \
 	AnnotationTest.cpp
 
@@ -379,6 +386,10 @@
 gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h: $(top_srcdir)/test/DebugProtoTest.thrift
 	$(THRIFT) --gen cpp $<
 
+gen-cpp/DoubleConstantsTest_constants.cpp gen-cpp/DoubleConstantsTest_constants.h: $(top_srcdir)/test/DoubleConstantsTest.thrift
+	$(THRIFT) --gen cpp $<
+
+
 gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h: $(top_srcdir)/test/EnumTest.thrift
 	$(THRIFT) --gen cpp $<
 
diff --git a/lib/cpp/test/RenderedDoubleConstantsTest.cpp b/lib/cpp/test/RenderedDoubleConstantsTest.cpp
new file mode 100644
index 0000000..0ca042b
--- /dev/null
+++ b/lib/cpp/test/RenderedDoubleConstantsTest.cpp
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#define EPSILON 0.0000001
+#include <typeindex>
+#include <typeinfo>
+#include <vector>
+
+#include "gen-cpp/DoubleConstantsTest_constants.h"
+using namespace thrift::test;
+
+#define BOOST_TEST_MODULE RenderedDoubleConstantsTest
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE(RenderedDoubleConstantsTest)
+
+BOOST_AUTO_TEST_CASE(test_rendered_double_constants) {
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1.0;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100.0;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807.0;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807.0;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308;
+    const double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43;
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE, EPSILON);
+    BOOST_CHECK_CLOSE(
+        g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST,
+        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE, EPSILON);
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST).hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE).hash_code());
+    BOOST_CHECK(
+        typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST)
+            .hash_code() ==
+        typeid(EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE).hash_code());
+}
+
+BOOST_AUTO_TEST_CASE(test_rendered_double_list) {
+    const std::vector<double> EXPECTED_DOUBLE_LIST{1.0,-100.0,100.0,9223372036854775807.0,-9223372036854775807.0,
+        3.14159265359,1000000.1,-1000000.1,1.7e+308,-1.7e+308,9223372036854775816.43,-9223372036854775816.43};
+    BOOST_CHECK_EQUAL(g_DoubleConstantsTest_constants.DOUBLE_LIST_TEST.size(), EXPECTED_DOUBLE_LIST.size());
+    for (unsigned int i = 0; i < EXPECTED_DOUBLE_LIST.size(); ++i) {
+        BOOST_CHECK_CLOSE(g_DoubleConstantsTest_constants.DOUBLE_LIST_TEST[i], EXPECTED_DOUBLE_LIST[i], EPSILON);
+    }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/lib/erl/Makefile.am b/lib/erl/Makefile.am
index 8867f88..06323b4 100644
--- a/lib/erl/Makefile.am
+++ b/lib/erl/Makefile.am
@@ -23,6 +23,7 @@
 		  $(THRIFT_OMIT_FILE) \
 		  ../../test/ConstantsDemo.thrift \
 		  ../../test/NameConflictTest.thrift \
+		  ../../test/DoubleConstantsTest.thrift \
 		  ../../test/ThriftTest.thrift
 
 if ERLANG_OTP16
diff --git a/lib/erl/test/test_rendered_double_constants.erl b/lib/erl/test/test_rendered_double_constants.erl
new file mode 100644
index 0000000..87fce81
--- /dev/null
+++ b/lib/erl/test/test_rendered_double_constants.erl
@@ -0,0 +1,68 @@
+%%
+%% Licensed to the Apache Software Foundation (ASF) under one
+%% or more contributor license agreements. See the NOTICE file
+%% distributed with this work for additional information
+%% regarding copyright ownership. The ASF licenses this file
+%% to you under the Apache License, Version 2.0 (the
+%% "License"); you may not use this file except in compliance
+%% with the License. You may obtain a copy of the License at
+%%
+%%   http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+%%
+
+-module(test_rendered_double_constants).
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+
+-include("gen-erl/double_constants_test_constants.hrl").
+
+-define(EPSILON, 0.0000001).
+
+rendered_double_constants_test() ->
+  ?assert(abs(1.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST) =< ?EPSILON),
+  ?assert(abs(-100.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST) =< ?EPSILON),
+  ?assert(abs(9223372036854775807.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST) =< ?EPSILON),
+  ?assert(abs(-9223372036854775807.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST) =< ?EPSILON),
+  ?assert(abs(3.14159265359 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST) =< ?EPSILON),
+  ?assert(abs(1000000.1 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON),
+  ?assert(abs(-1000000.1 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON),
+  ?assert(abs(1.7e+308 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST) =< ?EPSILON),
+  ?assert(abs(9223372036854775816.43 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON),
+  ?assert(abs(-1.7e+308 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST) =< ?EPSILON),
+  ?assert(abs(-9223372036854775816.43 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST)),
+  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST)).
+
+rendered_double_list_test() ->
+  ?assertEqual(12, length(?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)),
+  ?assert(abs(1.0 - lists:nth(1, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(-100.0 - lists:nth(2, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(100.0 - lists:nth(3, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(9223372036854775807.0 - lists:nth(4, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(-9223372036854775807.0 - lists:nth(5, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(3.14159265359 - lists:nth(6, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(1000000.1 - lists:nth(7, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(-1000000.1 - lists:nth(8, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(1.7e+308 - lists:nth(9, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(-1.7e+308 - lists:nth(10, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(9223372036854775816.43 - lists:nth(11, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+  ?assert(abs(-9223372036854775816.43 - lists:nth(12, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON).
+
+-endif. %% TEST
\ No newline at end of file
diff --git a/lib/java/gradle/generateTestThrift.gradle b/lib/java/gradle/generateTestThrift.gradle
index 9673e5b..c347917 100644
--- a/lib/java/gradle/generateTestThrift.gradle
+++ b/lib/java/gradle/generateTestThrift.gradle
@@ -74,6 +74,7 @@
     thriftCompile(it, 'ThriftTest.thrift')
     thriftCompile(it, 'JavaTypes.thrift')
     thriftCompile(it, 'DebugProtoTest.thrift')
+    thriftCompile(it, 'DoubleConstantsTest.thrift')
     thriftCompile(it, 'OptionalRequiredTest.thrift')
     thriftCompile(it, 'ManyOptionals.thrift')
     thriftCompile(it, 'JavaDeepCopyTest.thrift')
diff --git a/lib/java/test/org/apache/thrift/TestRenderedDoubleConstants.java b/lib/java/test/org/apache/thrift/TestRenderedDoubleConstants.java
new file mode 100644
index 0000000..d691fe3
--- /dev/null
+++ b/lib/java/test/org/apache/thrift/TestRenderedDoubleConstants.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.thrift;
+
+import java.util.List;
+import junit.framework.TestCase;
+import static org.junit.Assert.*;
+import org.junit.Test;
+import thrift.test.DoubleConstantsTestConstants;
+
+public class TestRenderedDoubleConstants extends TestCase {
+    private static final double EPSILON = 0.0000001;
+    private static final String ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST =
+        "failed to verify a double constant generated by Thrift (expected = %f, got = %f)";
+    private static final String ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_LIST_TEST =
+        "failed to verify a list item by Thrift (expected = %f, got = %f)";
+    private static final String ASSERTION_MESSAGE_FOR_TYPE_CHECKS =
+        "the rendered variable with name %s is not of double type";
+
+    // to make sure lists containing doubles are generated correctly
+    public void testRenderedDoubleList() throws Exception {
+        final double[] EXPECTED_LIST =
+            {1d,-100d,100d,9223372036854775807d,-9223372036854775807d,3.14159265359,1000000.1,-1000000.1,1.7e+308,
+             -1.7e+308,9223372036854775816.43,-9223372036854775816.43};
+        assertEquals(EXPECTED_LIST.length, DoubleConstantsTestConstants.DOUBLE_LIST_TEST.size());
+        for (int i = 0; i < EXPECTED_LIST.length; ++i) {
+            assertEquals(
+                String.format(
+                    ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_LIST_TEST,
+                    EXPECTED_LIST[i],
+                    DoubleConstantsTestConstants.DOUBLE_LIST_TEST.get(i)),
+                EXPECTED_LIST[i], DoubleConstantsTestConstants.DOUBLE_LIST_TEST.get(i), EPSILON);
+        }
+    }
+
+    // to make sure the variables inside Thrift files are generated correctly
+    public void testRenderedDoubleConstants() throws Exception {
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1.0;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100.0;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807.0;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807.0;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308;
+        final double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43;
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, EPSILON);
+        assertEquals(
+            String.format(
+                ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST,
+                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE,
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST),
+            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE,
+            DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST, EPSILON);
+        assertTrue(
+            String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST"),
+            Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST));
+        assertTrue(
+            String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST"),
+            Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST));
+        assertTrue(
+            String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST"),
+            Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST));
+        assertTrue(
+            String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST"),
+            Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST));
+        assertTrue(
+            String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST"),
+            Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST));
+        assertTrue(
+            String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST"),
+            Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST));
+        assertTrue(
+            String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST"),
+            Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST));
+        //assertTrue(
+        //    String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST"),
+        //    Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST));
+        assertTrue(
+            String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST"),
+            Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST));
+        //assertTrue(
+        //    String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST"),
+        //    Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST));
+        assertTrue(
+            String.format(
+                ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST"),
+            Double.class.isInstance(
+                DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST));
+    }
+}
diff --git a/lib/java/test/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java b/lib/java/test/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java
index 0b9c732..b8c4657 100644
--- a/lib/java/test/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java
+++ b/lib/java/test/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java
@@ -84,7 +84,7 @@
     struct.unsetDouble_byte_map();
     struct.unsetString_byte_map();
     struct.write(proto);
-    assertEquals("{\"a_byte\":127,\"a_i16\":32000,\"a_i32\":1000000000,\"a_i64\":1099511627775,\"a_double\":5.6789,\"a_string\":\"my string\",\"a_binary\":\"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\",\"true_field\":1,\"false_field\":0,\"empty_struct_field\":{},\"byte_list\":[-127,-1,0,1,127],\"i16_list\":[-1,0,1,32767],\"i32_list\":[-1,0,255,65535,16777215,2147483647],\"i64_list\":[-1,0,255,65535,16777215,4294967295,1099511627775,281474976710655,72057594037927935,9223372036854775807],\"double_list\":[0.1,0.2,0.3],\"string_list\":[\"first\",\"second\",\"third\"],\"boolean_list\":[1,1,1,0,0,0],\"struct_list\":[{},{}],\"i32_set\":[1,2,3],\"boolean_set\":[0,1],\"struct_set\":[{}],\"byte_byte_map\":{\"1\":2},\"boolean_byte_map\":{\"0\":0,\"1\":1},\"byte_i16_map\":{\"1\":1,\"2\":-1,\"3\":32767},\"byte_i32_map\":{\"1\":1,\"2\":-1,\"3\":2147483647},\"byte_i64_map\":{\"1\":1,\"2\":-1,\"3\":9223372036854775807},\"byte_double_map\":{\"1\":0.1,\"2\":-0.1,\"3\":1000000.0},\"byte_string_map\":{\"1\":\"\",\"2\":\"blah\",\"3\":\"loooooooooooooong string\"},\"byte_boolean_map\":{\"1\":1,\"2\":0},\"byte_map_map\":{\"0\":{},\"1\":{\"1\":1},\"2\":{\"1\":1,\"2\":2}},\"byte_set_map\":{\"0\":[],\"1\":[1],\"2\":[1,2]},\"byte_list_map\":{\"0\":[],\"1\":[1],\"2\":[1,2]}}", bufToString());
+    assertEquals("{\"a_byte\":127,\"a_i16\":32000,\"a_i32\":1000000000,\"a_i64\":1099511627775,\"a_double\":5.6789,\"a_string\":\"my string\",\"a_binary\":\"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\",\"true_field\":1,\"false_field\":0,\"empty_struct_field\":{},\"byte_list\":[-127,-1,0,1,127],\"i16_list\":[-1,0,1,32767],\"i32_list\":[-1,0,255,65535,16777215,2147483647],\"i64_list\":[-1,0,255,65535,16777215,4294967295,1099511627775,281474976710655,72057594037927935,9223372036854775807],\"double_list\":[0.1,0.2,0.3],\"string_list\":[\"first\",\"second\",\"third\"],\"boolean_list\":[1,1,1,0,0,0],\"struct_list\":[{},{}],\"i32_set\":[1,2,3],\"boolean_set\":[0,1],\"struct_set\":[{}],\"byte_byte_map\":{\"1\":2},\"boolean_byte_map\":{\"0\":0,\"1\":1},\"byte_i16_map\":{\"1\":1,\"2\":-1,\"3\":32767},\"byte_i32_map\":{\"1\":1,\"2\":-1,\"3\":2147483647},\"byte_i64_map\":{\"1\":1,\"2\":-1,\"3\":9223372036854775807},\"byte_double_map\":{\"1\":0.1,\"2\":-0.1,\"3\":1000000.1},\"byte_string_map\":{\"1\":\"\",\"2\":\"blah\",\"3\":\"loooooooooooooong string\"},\"byte_boolean_map\":{\"1\":1,\"2\":0},\"byte_map_map\":{\"0\":{},\"1\":{\"1\":1},\"2\":{\"1\":1,\"2\":2}},\"byte_set_map\":{\"0\":[],\"1\":[1],\"2\":[1,2]},\"byte_list_map\":{\"0\":[],\"1\":[1],\"2\":[1,2]}}", bufToString());
   }
 
   public void testThrowsOnCollectionKeys() throws TException {
diff --git a/lib/js/Gruntfile.js b/lib/js/Gruntfile.js
index 4aa450f..1dcead6 100644
--- a/lib/js/Gruntfile.js
+++ b/lib/js/Gruntfile.js
@@ -55,6 +55,9 @@
       ThriftGenDeepConstructor: {
         command: '../../compiler/cpp/thrift -gen js -o test ../../test/JsDeepConstructorTest.thrift'
       },
+      ThriftGenDoubleConstants: {
+        command: '../../compiler/cpp/thrift -gen js -o test ../../test/DoubleConstantsTest.thrift'
+      },
       ThriftGenES6: {
         command: '../../compiler/cpp/thrift -gen js -gen js:es6 -o test ../../test/ThriftTest.thrift'
       },
@@ -94,6 +97,14 @@
           ]
         }
       },
+      ThriftJS_DoubleRendering: {
+        options: {
+          '--ignore-ssl-errors': true,
+          urls: [
+            'http://localhost:8088/test-double-rendering.html'
+          ]
+        }
+      },
       ThriftWS: {
         options: {
           urls: [
diff --git a/lib/js/test/build.xml b/lib/js/test/build.xml
index 5b3b657..0ba3828 100755
--- a/lib/js/test/build.xml
+++ b/lib/js/test/build.xml
@@ -171,6 +171,9 @@
     <exec executable="${thrift.compiler}" failonerror="true">
       <arg line="--gen js:jquery ${thrift.dir}/test/ThriftTest.thrift" />
     </exec>
+    <exec executable="${thrift.compiler}" failonerror="true">
+      <arg line="--gen js:jquery ${thrift.dir}/test/DoubleConstantsTest.thrift" />
+    </exec>
   </target>
 
   <target name="test" description="run test suite (lint, unittest)" depends="lint, unittest"/>
diff --git a/lib/js/test/jsTestDriver.conf b/lib/js/test/jsTestDriver.conf
index b9702cd..eb1588c 100755
--- a/lib/js/test/jsTestDriver.conf
+++ b/lib/js/test/jsTestDriver.conf
@@ -7,6 +7,7 @@
 # dependencies
   - build/js/lib/jquery.js
   - build/js/thrift.js
+  - gen-js/DoubleConstantsTest_constants.js
   - gen-js/ThriftTest_types.js
   - gen-js/ThriftTest.js
 # the test suite
diff --git a/lib/js/test/test-double-rendering.html b/lib/js/test/test-double-rendering.html
new file mode 100644
index 0000000..240cb39
--- /dev/null
+++ b/lib/js/test/test-double-rendering.html
@@ -0,0 +1,55 @@
++<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+      <title>Rendering Double Constants in JS: Unit Test</title>
+
+      <script src="build/js/thrift.js"         type="text/javascript" charset="utf-8"></script>
+      <script src="gen-js/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
+      <script src="gen-js/ThriftTest.js"       type="text/javascript" charset="utf-8"></script>
+      <!-- double constants to check -->
+      <script src="gen-js/DoubleConstantsTest_types.js"         type="text/javascript" charset="utf-8"></script>
+
+      <!-- jQuery -->
+      <script type="text/javascript" src="../node_modules/jquery/dist/jquery.js" charset="utf-8"></script>
+
+      <!-- QUnit Test framework-->
+      <script type="text/javascript" src="../node_modules/qunit/qunit/qunit.js" charset="utf-8"></script>
+      <link rel="stylesheet" href="../node_modules/qunit/qunit/qunit.css" type="text/css" media="screen" />
+
+      <!-- the Test Suite-->
+      <script type="text/javascript" src="test-double-rendering.js" charset="utf-8"></script>
+    </head>
+<body>
+  <h1 id="qunit-header">Rendering Double Constants in JS: Unit Test</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div>
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>
+  <!-- Uncomment this to check the validity. This significantly slows down the test.
+  <p>
+      <a href="http://validator.w3.org/check/referer"><img
+          src="http://www.w3.org/Icons/valid-xhtml10"
+          alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+  </p>
+  -->
+</body>
+</html>
diff --git a/lib/js/test/test-double-rendering.js b/lib/js/test/test-double-rendering.js
new file mode 100644
index 0000000..5d9cd2a
--- /dev/null
+++ b/lib/js/test/test-double-rendering.js
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ /* jshint -W100 */
+
+/*
+ * JavaScript test suite for double constants inside
+ * DebugProtoTest.thrift. These tests will run against Normal (-gen js)
+ * Apache Thrift interfaces.
+ *
+ * Synchronous blocking calls should be identical in both
+ * Normal and jQuery interfaces. All synchronous tests belong
+ * here.
+ *
+ * Asynchronous success callbacks passed as the last parameter
+ * of an RPC call should be identical in both Normal and jQuery
+ * interfaces. Async success tests belong here.
+ *
+ * Asynchronous exception processing is different in Normal
+ * and jQuery interfaces. Such tests belong in the test-nojq.js
+ * or test-jq.js files respectively. jQuery specific XHR object
+ * tests also belong in test-jq.js. Do not create any jQuery
+ * dependencies in this file or in test-nojq.js
+ *
+ * To compile client code for this test use:
+ *      $ thrift -gen js ThriftTest.thrift
+ *      $ thrift -gen js DebugProtoTest.thrift
+ *
+ * See also:
+ * ++ test-nojq.js for "-gen js" only tests
+ */
+
+// double assertion threshold
+var EPSILON = 0.0000001;
+
+// Work around for old API used by QUnitAdapter of jsTestDriver
+if (typeof QUnit.log == 'function') {
+  // When using real QUnit (fron PhantomJS) log failures to console
+  QUnit.log(function(details) {
+    if (!details.result) {
+      console.log('======== FAIL ========');
+      console.log('TestName: ' + details.name);
+      if (details.message) console.log(details.message);
+      console.log('Expected: ' + details.expected);
+      console.log('Actual  : ' + details.actual);
+      console.log('======================');
+    }
+  });
+}
+
+QUnit.module('Double rendering');
+
+  QUnit.test('Double (rendering)', function(assert) {
+    console.log('Double rendering test -- starts');
+    var EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308;
+    var EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43;
+    assert.ok(
+        Math.abs(EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT - DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT -
+            DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT -
+            DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT -
+            DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS -
+            DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE -
+            DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE -
+            DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE -
+            DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE -
+            DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE -
+            DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST) <= EPSILON);
+    assert.ok(
+        Math.abs(
+            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE -
+            DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST) <= EPSILON);
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, 'number');
+    assert.equal(typeof DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST, 'number');
+    var EXPECTED_DOUBLE_LIST =
+        [1,-100,100,9223372036854775807,-9223372036854775807,3.14159265359,1000000.1,-1000000.1,1.7e+308,-1.7e+308,
+            9223372036854775816.43,-9223372036854775816.43];
+    assert.equal(DOUBLE_LIST_TEST.length, EXPECTED_DOUBLE_LIST.length);
+    for (var i = 0; i < EXPECTED_DOUBLE_LIST.length; ++i) {
+           assert.ok(Math.abs(EXPECTED_DOUBLE_LIST[i] - DOUBLE_LIST_TEST[i]) <= EPSILON);
+    }
+    console.log('Double rendering test -- ends');
+  });
+
diff --git a/test/DoubleConstantsTest.thrift b/test/DoubleConstantsTest.thrift
new file mode 100644
index 0000000..c9212ab
--- /dev/null
+++ b/test/DoubleConstantsTest.thrift
@@ -0,0 +1,17 @@
+namespace java thrift.test
+namespace cpp thrift.test
+
+// more tests on double constants (precision and type checks)
+const double DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST = 1
+const double DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST = -100
+const double DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST = 9223372036854775807
+const double DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST = -9223372036854775807
+const double DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST = 3.14159265359
+const double DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST = 1000000.1
+const double DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST = -1000000.1
+const double DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST = 1.7e+308
+const double DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST = 9223372036854775816.43
+const double DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST = -1.7e+308
+const double DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST = -9223372036854775816.43
+
+const list<double> DOUBLE_LIST_TEST = [1,-100,100,9223372036854775807,-9223372036854775807,3.14159265359,1000000.1,-1000000.1,1.7e+308,-1.7e+308,9223372036854775816.43,-9223372036854775816.43]
diff --git a/test/Makefile.am b/test/Makefile.am
index cb3d9aa..7267066 100755
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -134,6 +134,7 @@
 	BrokenConstants.thrift \
 	ConstantsDemo.thrift \
 	DebugProtoTest.thrift \
+	DoubleConstantsTest.thrift \
 	DenseLinkingTest.thrift \
 	DocTest.thrift \
 	EnumTest.thrift \
diff --git a/test/py/Makefile.am b/test/py/Makefile.am
index b3513dd..8296200 100644
--- a/test/py/Makefile.am
+++ b/test/py/Makefile.am
@@ -23,24 +23,31 @@
 thrift_gen =                                    \
         gen-py/ThriftTest/__init__.py           \
         gen-py/DebugProtoTest/__init__.py \
+        gen-py/DoubleConstantsTest/__init__.py \
         gen-py/Recursive/__init__.py \
         gen-py-default/ThriftTest/__init__.py           \
         gen-py-default/DebugProtoTest/__init__.py \
+        gen-py-default/DoubleConstantsTest/__init__.py \
         gen-py-default/Recursive/__init__.py \
         gen-py-slots/ThriftTest/__init__.py           \
         gen-py-slots/DebugProtoTest/__init__.py \
+        gen-py-slots/DoubleConstantsTest/__init__.py \
         gen-py-slots/Recursive/__init__.py \
         gen-py-oldstyle/ThriftTest/__init__.py \
         gen-py-oldstyle/DebugProtoTest/__init__.py \
+        gen-py-oldstyle/DoubleConstantsTest/__init__.py \
         gen-py-oldstyle/Recursive/__init__.py \
         gen-py-no_utf8strings/ThriftTest/__init__.py \
         gen-py-no_utf8strings/DebugProtoTest/__init__.py \
+        gen-py-no_utf8strings/DoubleConstantsTest/__init__.py \
         gen-py-no_utf8strings/Recursive/__init__.py \
         gen-py-dynamic/ThriftTest/__init__.py           \
         gen-py-dynamic/DebugProtoTest/__init__.py \
+        gen-py-dynamic/DoubleConstantsTest/__init__.py \
         gen-py-dynamic/Recursive/__init__.py \
         gen-py-dynamicslots/ThriftTest/__init__.py           \
         gen-py-dynamicslots/DebugProtoTest/__init__.py \
+        gen-py-dynamicslots/DoubleConstantsTest/__init__.py \
         gen-py-dynamicslots/Recursive/__init__.py
 
 
diff --git a/test/py/RunClientServer.py b/test/py/RunClientServer.py
index 7c0f787..b213d1a 100755
--- a/test/py/RunClientServer.py
+++ b/test/py/RunClientServer.py
@@ -38,6 +38,7 @@
 SCRIPTS = [
     'FastbinaryTest.py',
     'TestFrozen.py',
+    'TestRenderedDoubleConstants.py',
     'TSimpleJSONProtocolTest.py',
     'SerializationTest.py',
     'TestEof.py',
diff --git a/test/py/TestRenderedDoubleConstants.py b/test/py/TestRenderedDoubleConstants.py
new file mode 100644
index 0000000..20903d8
--- /dev/null
+++ b/test/py/TestRenderedDoubleConstants.py
@@ -0,0 +1,177 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import unittest
+
+from DoubleConstantsTest import constants
+
+#
+# In order to run the test under Windows. We need to create symbolic link
+# name 'thrift' to '../src' folder by using:
+#
+# mklink /D thrift ..\src
+#
+
+
+class TestRenderedDoubleConstants(unittest.TestCase):
+    ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST = \
+        "failed to verify a double constant generated by Thrift (expected = %f, got = %f)"
+    ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_LIST_TEST =\
+        "failed to verify a list item by Thrift (expected = %f, got = %f)"
+    ASSERTION_MESSAGE_FOR_TYPE_CHECKS = "the rendered variable with name %s is not of double type"
+
+    # to make sure the variables inside Thrift files are generated correctly
+    def test_rendered_double_constants(self):
+        EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1.0
+        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100.0
+        EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807.0
+        EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807.0
+        EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359
+        EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1
+        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1
+        EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308
+        EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43
+        EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308
+        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT, places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT, constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT,
+            places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT,
+                constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT,
+            places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT,
+                constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT,
+            places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT,
+                constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST,
+            EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS, places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS,
+                constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE,
+            places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE,
+                constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST,
+            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE, places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE,
+                constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE, places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE,
+                constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST,
+            EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE, places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE,
+                constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE, places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE,
+                constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST))
+        self.assertAlmostEqual(
+            constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST,
+            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE, places=7,
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
+                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE,
+                constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST))
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST")
+        self.assertTrue(
+            isinstance(constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST, float),
+            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
+            "DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST")
+
+    # to make sure the variables inside Thrift files are generated correctly
+    def test_rendered_double_list(self):
+        EXPECTED_DOUBLE_LIST = [1.0, -100.0, 100.0, 9223372036854775807.0, -9223372036854775807.0, 3.14159265359,
+                                1000000.1, -1000000.1, 1.7e+308, -1.7e+308, 9223372036854775816.43,
+                                -9223372036854775816.43]
+        self.assertEqual(len(constants.DOUBLE_LIST_TEST), len(EXPECTED_DOUBLE_LIST))
+        for i, expectedValue in enumerate(EXPECTED_DOUBLE_LIST):
+            self.assertAlmostEqual(constants.DOUBLE_LIST_TEST[i], expectedValue, places=7)
+
+
+def suite():
+    suite = unittest.TestSuite()
+    loader = unittest.TestLoader()
+    suite.addTest(loader.loadTestsFromTestCase(TestRenderedDoubleConstants))
+    return suite
+
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
diff --git a/test/py/generate.cmake b/test/py/generate.cmake
index 46263c8..4ed14cc 100644
--- a/test/py/generate.cmake
+++ b/test/py/generate.cmake
@@ -21,6 +21,13 @@
 generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:dynamic gen-py-dynamic)
 generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:dynamic,slots gen-py-dynamicslots)
 
+generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py gen-py-default)
+generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:slots gen-py-slots)
+generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:old_style gen-py-oldstyle)
+generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:no_utf8strings gen-py-no_utf8strings)
+generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:dynamic gen-py-dynamic)
+generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:dynamic,slots gen-py-dynamicslots)
+
 generate(${MY_PROJECT_DIR}/test/Recursive.thrift py gen-py-default)
 generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:slots gen-py-slots)
 generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:old_style gen-py-oldstyle)