Tracktion / choc

A collection of header only classes, permissively licensed, to provide basic useful tasks with the bare-minimum of dependencies.
Other
529 stars 47 forks source link

Bug Report: setMember with float = 1.0 will be stored as 1 and parsed as int64 #53

Closed manol-o closed 5 months ago

manol-o commented 5 months ago

Hi, first of all thanks a lot for the nice work of this library!

I encountered an issue, code should make it clear:

    auto floatVal = choc::value::Value (1.0f);

    auto myVal = choc::value::createObject ("MyVal");
    myVal.setMember ("TestMember", floatVal);

    auto tmpString = choc::json::toString (myVal);

    auto myOtherVal = choc::json::parse (tmpString);

    if (myOtherVal["TestMember"].isFloat64())
    {
        // we should reach this point!
    }
    else if (myOtherVal["TestMember"].isInt64())
    {
        // but we come here, because its stored as 1 and not 1.0
    }

Again thanks a lot for the great work

manol-o commented 5 months ago

in choc_JSON.h:182

if (std::isfinite (value))  return choc::text::floatToString (value, -1, true);

to

if (std::isfinite (value))  return choc::text::floatToString (value, -1, false);

fixes the issue. (changed bool value is omitPointIfPossible)

julianstorer commented 5 months ago

I guess we haven't noticed a problem because if I want a double, I'd normally call val["foo"].get<double>() which will do the cast for you even if it's stored as an integer. You'd only hit a snag if you call val["foo"].getFloat64(), which is strict about checking the type.

But.. I don't think there's anything wrong with the change you're suggesting, it does seem pretty reasonable to always write a json double with the point, and I can't think of any downside to that