Open JasonYang-MSFT opened 8 years ago
Could you go into a bit more detail about the problems this causes for your application? Why do you specifically need the number '8' to be serialized as '8.0' instead of '8'?
If this is to ease manipulation with another cpprestsdk-using program, we have an API value::is_number()
which will check if the parsed value is any numeric type (int, double, or otherwise). The function value::as_double()
will convert any internal number type into a double for your program.
@ras0219-msft We use this to store data in a NoSQL database through network. Doubles were serialized as string. So serialize 8.0 as 8 will cause a total different result.
This is due to the format specifier used for formatting numbers:
"%.*g"
The number 1.0 will be serialized as "1", which will be interpreted as an integer when you try to read it back. I know it's possible to use is_number() and then as_double() or as_int(), but this requires us to make assumptions in our code when it should've been possible to determine data type from the json string alone. That is, if 1.0 was correctly serialized as "1.0", then we can avoid having to do an int->double conversion.
You get:
and it's impossible to determine if the int should be a double or an integer without encoding additional information elsewhere in the JSON (awful).
We're actually blocked on this bug and may need to explore using other JSON libs that don't have this limitation.
When is something going to be done about this bug? I am also running into this issue. It's important that doubles stay doubles with digits and that integers stay integers without digits after the serialisation!
While we use web::json::value::object contains double value such as 8.0, the serializing result would be 8. After deserialization, it become an integer with value 8, not a double as it should be.
Sample input: string key = "DoubleProperty"; double value = 8.0; Sample serialization: "{"DoubleProperty":8}" Sample deserialization: string key = "DoubleProperty"; int value = 8;
Sample code is followed:
include
include "cpprest\json.h"
int main() { std::vector<std::pair<utility::string_t, web::json::value> > fields; fields.reserve(1); double double_value = 8.0; web::json::value property_value = web::json::value(double_value); fields.push_back(std::make_pair(_XPLATSTR("DoubleProperty"), std::move(property_value)));
}
After a short investigation, we find out that the problem is in serialization. Deserialization could correctly parse 8.0 as a double value, but serialization wrongly serialize 8.0 as 8.
The code might cause this problem is followed: Windows: https://github.com/Microsoft/cpprestsdk/blob/master/Release/src/json/json_serialization.cpp#L248 Linux: https://github.com/Microsoft/cpprestsdk/blob/master/Release/src/json/json_serialization.cpp#L201
The main cause should be the format string("%.*g") use in _swprintf_s_l for Windows and snprintf for Linux. As the description in https://msdn.microsoft.com/zh-cn/library/0ecbz014.aspx, it will lose any trailing zeros which cause 8.0 printed as 8