micropython round
-
>>> round(691.69, 1) 691.7
makes sense
>>> round(691.49, 1) 691.5
likewise
>>> round(691.59, 1) 691.5999
how come?
-
@kjm This is a recurring discussion in Micropython. See also for instance:
https://forum.micropython.org/viewtopic.php?f=2&t=802
https://github.com/micropython/micropython/issues/3516But still, the number which the raspi (C-Python) displays is not the number internally stored. However, using a 64 bit float representation, the error is way smaller.
Note also, that rounding was improved in the micrpython.org branch:
https://github.com/micropython/micropython/commit/b768cc6ca8ed6d7430b86dc7ccb9ee2391b3a251
For the esp8266 build, I get:MicroPython v1.9.4-704-g62b4bebf-dirty on 2018-12-04; ESP module with ESP8266 Type "help()" for more information. >>> round(691.59, 1) 691.6
But not so for the ESP32 build. The loboris branch again delivers 691.6
But, so sum up: it is not the rounding, that "fails", it's the display of decimal fractions.
If you just enter 691.6, REPL will show 691.5999. Similar with other numbers, but not every number.
-
@mfalkvidd I miss my raspberry pi
>>> round(691.59, 1) 691.6
-
This post is deleted!
-
And it is a good practice to compare values with a delta.
as you can see, not all numbers can be represented. So instead ofif val == 191.6: #do something
you shall do something like
delta = 0.1 target = 691.6 if target-delta >= val && val <= target+delta: #do something
So you take care that not all decimal values are represented. Which delta you shall choose depends on the precission you need and how your values a calculated. If in this case you multiply the error of 0.0001 by 10,000, you may have to use a huge delta of 1.
Be careful with zero. On some architectures 0 does not equals -0. Lucky us, on the ESP32 it seems to be equal.
-
@kjm Decimal fractions cannot always be precisely expressed by a binary number. What you see is the attempt to get as close as possible to the value of 691.6. If a number is a binary fraction, like 591.5, it will be shown precisely, otherwise it is not guaranteed. If you use formatted print, the representation is rounded as expected. try
print("%.1f" % round(691.59, 1))
P.S.: if you just enter 591.6 at the REPL, it should also be echoed as 591.5999
-
@kjm 691.6 (and many other numbers) can not be representex correctly by a floating point number. Try entering the values into https://www.h-schmidt.net/FloatConverter/IEEE754.html and you'll see that there will be a large error.
Longer explanation: http://www.phys.uconn.edu/~rozman/Courses/P2200_15F/downloads/floating-point-guide-2015-10-15.pdf#page3