forked from bblanchon/ArduinoJson
JsonDeserializer: use float when the value has few digits
This commit is contained in:
1 parent
fd6314e132
commit
1f7a3f3174
8 files changed
+163
-28
No files matched your search
@@ -520,16 +520,30 @@ class JsonDeserializer {
|
||||
auto number = parseNumber(buffer_);
|
||||
switch (number.type()) {
|
||||
case NumberType::UnsignedInteger:
|
||||
result.setInteger(number.asUnsignedInteger(), resources_);
|
||||
return DeserializationError::Ok;
|
||||
if (result.setInteger(number.asUnsignedInteger(), resources_))
|
||||
return DeserializationError::Ok;
|
||||
else
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
case NumberType::SignedInteger:
|
||||
result.setInteger(number.asSignedInteger(), resources_);
|
||||
return DeserializationError::Ok;
|
||||
if (result.setInteger(number.asSignedInteger(), resources_))
|
||||
return DeserializationError::Ok;
|
||||
else
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
case NumberType::Float:
|
||||
result.setFloat(number.asFloat(), resources_);
|
||||
return DeserializationError::Ok;
|
||||
if (result.setFloat(number.asFloat(), resources_))
|
||||
return DeserializationError::Ok;
|
||||
else
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
case NumberType::Double:
|
||||
if (result.setFloat(number.asDouble(), resources_))
|
||||
return DeserializationError::Ok;
|
||||
else
|
||||
return DeserializationError::NoMemory;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return DeserializationError::InvalidInput;
|
||||
|
||||
@@ -21,18 +21,27 @@ enum class NumberType : uint8_t {
|
||||
Invalid,
|
||||
Float,
|
||||
SignedInteger,
|
||||
UnsignedInteger
|
||||
UnsignedInteger,
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
Double,
|
||||
#endif
|
||||
};
|
||||
|
||||
union NumberValue {
|
||||
NumberValue() {}
|
||||
NumberValue(JsonFloat x) : asFloat(x) {}
|
||||
NumberValue(float x) : asFloat(x) {}
|
||||
NumberValue(JsonInteger x) : asSignedInteger(x) {}
|
||||
NumberValue(JsonUInt x) : asUnsignedInteger(x) {}
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
NumberValue(double x) : asDouble(x) {}
|
||||
#endif
|
||||
|
||||
JsonInteger asSignedInteger;
|
||||
JsonUInt asUnsignedInteger;
|
||||
JsonFloat asFloat;
|
||||
float asFloat;
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
double asDouble;
|
||||
#endif
|
||||
};
|
||||
|
||||
class Number {
|
||||
@@ -41,9 +50,12 @@ class Number {
|
||||
|
||||
public:
|
||||
Number() : type_(NumberType::Invalid) {}
|
||||
Number(JsonFloat value) : type_(NumberType::Float), value_(value) {}
|
||||
Number(float value) : type_(NumberType::Float), value_(value) {}
|
||||
Number(JsonInteger value) : type_(NumberType::SignedInteger), value_(value) {}
|
||||
Number(JsonUInt value) : type_(NumberType::UnsignedInteger), value_(value) {}
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
Number(double value) : type_(NumberType::Double), value_(value) {}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
T convertTo() const {
|
||||
@@ -54,6 +66,10 @@ class Number {
|
||||
return convertNumber<T>(value_.asSignedInteger);
|
||||
case NumberType::UnsignedInteger:
|
||||
return convertNumber<T>(value_.asUnsignedInteger);
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
case NumberType::Double:
|
||||
return convertNumber<T>(value_.asDouble);
|
||||
#endif
|
||||
default:
|
||||
return T();
|
||||
}
|
||||
@@ -73,10 +89,17 @@ class Number {
|
||||
return value_.asUnsignedInteger;
|
||||
}
|
||||
|
||||
JsonFloat asFloat() const {
|
||||
float asFloat() const {
|
||||
ARDUINOJSON_ASSERT(type_ == NumberType::Float);
|
||||
return value_.asFloat;
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
double asDouble() const {
|
||||
ARDUINOJSON_ASSERT(type_ == NumberType::Double);
|
||||
return value_.asDouble;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
inline Number parseNumber(const char* s) {
|
||||
@@ -192,10 +215,19 @@ inline Number parseNumber(const char* s) {
|
||||
if (*s != '\0')
|
||||
return Number();
|
||||
|
||||
JsonFloat final_result =
|
||||
make_float(static_cast<JsonFloat>(mantissa), exponent);
|
||||
|
||||
return Number(is_negative ? -final_result : final_result);
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
bool isDouble = exponent < -FloatTraits<float>::exponent_max ||
|
||||
exponent > FloatTraits<float>::exponent_max ||
|
||||
mantissa > FloatTraits<float>::mantissa_max;
|
||||
if (isDouble) {
|
||||
auto final_result = make_float(double(mantissa), exponent);
|
||||
return Number(is_negative ? -final_result : final_result);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
auto final_result = make_float(float(mantissa), exponent);
|
||||
return Number(is_negative ? -final_result : final_result);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
Reference in new issue
Block a user