diff --git a/include/common/utils.hpp b/include/common/utils.hpp index 3ccfbda..e7219b1 100644 --- a/include/common/utils.hpp +++ b/include/common/utils.hpp @@ -2,6 +2,9 @@ #pragma once +#include +#include +#include #include #include @@ -233,6 +236,21 @@ inline constexpr string_t null_string() template inline string_t to_basic_string(any_t&& arg) { +#ifdef MEOJSON_KEEP_FLOATING_PRECISION + using real_type = std::remove_reference_t; + if constexpr (std::is_floating_point_v) { + if constexpr (std::is_same_v) { + std::ostringstream oss; + oss << std::setprecision(std::numeric_limits::max_digits10) << arg; + return oss.str(); + } + else if constexpr (std::is_same_v) { + std::wostringstream oss; + oss << std::setprecision(std::numeric_limits::max_digits10) << arg; + return oss.str(); + } + } +#endif if constexpr (std::is_same_v) { return std::to_string(std::forward(arg)); } diff --git a/test/main.cpp b/test/main.cpp index 90f5a0f..3316cea 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -2,6 +2,7 @@ #include "include_test.h" #include "json5_test.h" +#include "precision_test.h" #include "serializing_test.h" int main() @@ -23,6 +24,9 @@ int main() std::cout << "\n*** json5_test ***\n" << std::endl; success &= test_json5(); + std::cout << "\n*** precision_test ***\n" << std::endl; + success &= precision_test(); + if (!success) { std::cout << "\n****** Test failed ******\n" << std::endl; return -1; diff --git a/test/precision_test.cpp b/test/precision_test.cpp new file mode 100644 index 0000000..52caa22 --- /dev/null +++ b/test/precision_test.cpp @@ -0,0 +1,18 @@ +#define MEOJSON_KEEP_FLOATING_PRECISION + +#include "../include/json.hpp" + +#include +#include + +bool precision_test() +{ + double value = 3.141592653589793; + json::object obj_old = json::object { { "double", value } }; + std::string obj_str = obj_old.to_string(); + std::cout << obj_str << std::endl; + json::object obj_new = json::parse(obj_str).value().as_object(); + std::cout << "old:" << std::hexfloat << value << std::endl; + std::cout << "new:" << std::hexfloat << obj_new.at("double").as_double() << std::endl; + return obj_new.at("double").as_double() == value; +} diff --git a/test/precision_test.h b/test/precision_test.h new file mode 100644 index 0000000..42cccaa --- /dev/null +++ b/test/precision_test.h @@ -0,0 +1,3 @@ +#pragma once + +extern bool precision_test();