The values of type "float" seem to be internally treated as values of type "double". This leads to an issue with their text representation. For example, the snippet below:
json j;
j["test"] = 0.42f;
std::cout << j.dump() << std::endl;
produces this json output:
{"test":0.41999998688697815}
I experimented a bit with float values, and found out, that a workaround, like that:
namespace nlohmann
{
namespace detail
{
template<>
inline char* to_chars<json::number_float_t>(char* first, char* last, json::number_float_t value)
{
std::ostringstream s;
s << value;
std::string buf = oss.str();
return std::copy(buf.begin(), buf.end(), first);
}
}
}
can impove floats' representation, and produce the following json:
{"test":0.42}
I know, that floating point arithmetics is a sensitive topic, but I think, floats' representation in human-readable format should be improved, if possible.
Isn't JSON pretty well known (if not defined) as having floats being 64-bit, I.E. C++ doubles?
Also ostringstream streaming is sloooooooow, if anything is performance sensitive you don't want to use it.
A lot of work has been put into both the performance and correctness of the current code.
The default floating point storage type is indeed double, and all values are converted to it before storage. The fact that it's single precision is lost long before you convert to text. While your code works for that one particular value, it is wrong for many more values as it loses precision.
As @gregmarr stated, that behavior is intended. You may want to try to give float as template argument to the basic_json class.
Thanks for the hint about template argument, I'll try it - I overlooked this option somehow!
Example:
#include <iostream>
#include "json.hpp"
int main() {
using json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;
json j;
j["test"] = 0.42f;
std::cout << j.dump() << std::endl;
}
Output:
{"test":0.42}
Most helpful comment
As @gregmarr stated, that behavior is intended. You may want to try to give
floatas template argument to thebasic_jsonclass.