arduino-libraries/Arduino_JSON

Getting wrong values on double or long parsing and stringify

marcpouliot opened this issue · 2 comments

I'm using the "JSONObject" example with Arduino Nano.

I have changed the following line:

const char input[] = "{\"result\":true,\"count\":42,\"foo\":\"bar\"}";

to:

const char input[] = "{\"result\":true,\"count\":551489800,\"foo\":\"bar\"}";

(changed the value of count from 42 to 551489800)

The value returned is 551489792 on parsing and on stringify.

Using different values, I realize that it seems that the 4th byte of the long or double is not added properly. (OK up to FFFFFF, 3 bytes.) But added investigation shows that the problem occurs on last byte when 4th byte is present.

If I try different "count" values, I get :

Value Correctly handled? Notes
20DF1108 No Converted to 20DF1100
20DF1118 No Converted to 20DF1100
20DF10FF No Converted to 20DF1100
DF10EF Yes
FFFFFF Yes
1DF13DF No Converted to 1DF13E0
1000000 Yes
7000000 Yes
7DF10EF No converted to 7DF10F0
F000000 Yes
FDF10EF No Converted to FDF10F0
10000000 Yes
100D0000 Yes
100D0100 Yes
100F10EF No converted to 100F10E0

I include the modified JSONObject.ino
JSONObject.zip

Answering myself.
This seems to be the same problem as in https://forum.arduino.cc/index.php?topic=546985.0
It seems the internals of the library does not convert properly as in the previous example.
For a quick solution, I use strings (number surrounded by double quotes) instead of a number (without double quotes) to transfer the data and I convert with atol (which does not implement the error) instead of string.toDouble() - which implements the error.
(Maybe that's the problem ?)
I include a small TestDouble.ino file.

TestDouble.zip

tinxx commented

It looks like I'm having the same problem in reverse:

float   a1 = 982.661255f;
double  b1 = 0.001 * (int)(1000 * a1); // clip some decimals
JSONVar a2 = a1;
JSONVar b2 = b1;
Serial.printf("%f / %f --> ", a1, b1);
Serial.print(a2);
Serial.print(" / ");
Serial.println(b2);

Generates the output:

982.661255 / 982.661000 --> 982.6612548828125 / 982.66100000000006

I expected the last output to be 982.661 or 982.661000 instead of 982.66100000000006.