Closed git-developer closed 1 year ago
I see. I would rather move precision var to MqttValue(double val)
constructor and MqttValue::fromDouble
and use it when MqttValue::mType
is SourceType::DOUBLE
and MqttValue::toString
is called.
This way we avoid multiple conversions in future when payload_type: binary will be supported.
That's a good idea. I added a commit here, because a second branch would only produce conflicts and work.
I found out that it's not enough to return a correctly formatted string in getString()
, because createConvertedValue() uses getDouble()
when writing the value to JSON. One could use rapidjson::Writer.SetMaxDecimalPlaces()
to handle this, but this would require exporting the precision outside of MqttValue
.
I chose a different approach by rounding the double value when it is set to MqttValue
. This results in a double value with the desired precision in JSON, is compatible to the current code base and fixes the issues on the i386 platform.
The original number-based rounding algorithm works if the int
-cast is replaced by std::round
, i.e. no string conversions are required for rounding. I changed that accordingly.
This PR fixes floating point related issues. The issues can be reproduced when building for target platform
linux/386
.Logs:
Excerpt from the build log:
The test failures seem to be caused by casts between
double
andint
. I can't tell why this only happens on i386 platform, though; could be related to different compiler defaults for floating point calculations (just a guess).Problem 1
exprconv_tests:136
:int16_t(regValue)
results in-32768
instead of-1
. The fix uses thetoNumber()
function, as all other custom functions do. I also had success withint16_t(static_cast<uint16_t>(regValue))
.Problem 2
The other 2 tests fail because of a diff in the JSON document:
mqtt_state_map_conv_tests:35
:mqtt_named_scalar_conv_tests:36
:This problem can be narrowed down to the
dummy
variable inConverterTools::round()
; it seems to be caused by casts betweendouble
andint
.Conclusion
After struggling with these rounding related issues, I have a suggestion. I think that in
ConverterTools
:should be replaced by
The reason is that there's no proper way to round a floating point variable to an exact value. The converters apply roundings just before creating an MqttValue, finally resulting in a string in the JSON. So in my opinion it's safer to return a string instead of a double as rounding result, to be sure that the value looks exactly as requested.
The only location that uses the rounding result as number is
DivideConverter.toModbus()
, but the value is stored asint32_t
so the effect of rounding looks quite limited to me.If you agree that rounding should result in a
string
instead of adouble
, I will open another PR.