-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ADD command uses wrong rounding (1.00 + 0.005 = 1.00) #4420
Comments
Sorry, Tasmota uses 2 decimals only |
Yes, that's right. But why does the add command round up correct any .006 up to .009 and round down correcty any .004 to .001 but just the .005 is wrong - rounding down instead of up? |
Sorry, the rounding is like that because it uses just 2 decimals, so it rounds to the closest value. It is correct like that. |
No, as "rounding to the closest value" everywhere in the world ist defined as "round up if the next digit is >=5. If you have a precision of two decimals only: |
Having looked at the code, I am quite sure that it's not a Tasmota bug but a really nasty bug in the dtostrf() function in the standard library. |
When you enter anything in the console is stored as text, then when Tasmota see that is a command for numbers like ADD, it converts the text to number in the line: So, the conversion and rounding is done by CHARTODOUBLE instruction. |
More downwards, you call dtostrfd which itself calls dtostrf() and that one definitely has a rounding bug. |
In which line you see that? The code directly related to ADD command makes the conversion with chartodouble. |
The CharToDouble function only converts the two values to the double data types. As you said, the variables are stored as text, the parameter to be added is coming as text, so CharToDouble converts both to double and does NOT reflect any precision restriction at that time. (see support.ino) in xdrv_10_rules.ino, you see
So after the two converted double values are added and stored to the tempvar of still double type, the line in support.ino, dtostrfd is defined (around line 197 in my version) and it's just a secure wrapper around using dtostrf() from the standard library. That one really does the conversion of the double type value to the string, with precision of 2 digits (which you use as a parameter). That functions does rounding. But it does it wrong, see example. Possibly fixed in a newer ESP library, I can't check. -> not a Tasmota bug, but a bug in dtostrf() |
Fun fact: I recompiled Tasmota, replacing the target precision of "2" with "4" for the ADD, SUB, ... SCALE functions, and now rounding works correctly:
Then, I changed the code back to use 2 digits precision, and - WONDER WHY - the bug is gone.
The only difference is that I used Tasmota version 6.3.0.5 before and now it's 6.3.0.8, and my Atom did some updates. For me, it's solved, but I would recommend to keep an eye on the dtostrf() function. Net net is full of statements that it's buggy. Last question: was there any reason why the precision of the mathematic commands' result was set hard to "2"? It's a pity as it
|
I like your idea of a configurable precision 👍 |
Proprosed PR #4466 for the addition of command |
Bug (minor): the numeric commands have a two digit precision after the decimal point (.00 to .99). At least the ADD command uses wrong rounding-up. It does NOT round up starting with "5" as the next digit, but with "6".
1.00 + 0.004 = 1.00 (correct)
1.00 + 0.005 = 1.00 (wrong)
1.00 + 0.006 = 1.01 (correct)
Also, make sure these boxes are checked [x] before submitting your issue - Thank you!
status 0
:To Reproduce
commands:
21:33:38 CMD: var1 1
21:33:38 RSL: RESULT = {"Var1":"1"}
21:33:47 CMD: add1 0.005
21:33:47 RSL: RESULT = {"Add1":"1.00"}
21:41:42 CMD: var1 1
21:41:42 RSL: RESULT = {"Var1":"1"}
21:41:45 CMD: add1 0.005
21:41:45 RSL: RESULT = {"Add1":"1.00"}
I would have expected the Result 1.01 also when adding 0.005 to 1.00.
The text was updated successfully, but these errors were encountered: