Page 1 of 3

MicroPython round() Function

Posted: Sun Jul 12, 2015 4:21 am
by John Roach
Is there a version in Micropython of the standard Python 3 round() function that accepts two parameters: for example round(3.1416,3)? In my pyboard version this generates an error, eg 'function takes 1 positional arguments but 2 were given.

Re: MicroPython round() Function

Posted: Sun Jul 12, 2015 10:35 am
by Turbinenreiter
Are you on the latest build?

Currently, round with N>0 is not implemented.

Code: Select all

>>> round(3.22, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NotImplementedError: round(..., N>0)
>>> round(3.22)
3

Re: MicroPython round() Function

Posted: Sun Jul 12, 2015 11:17 am
by Turbinenreiter
I committed a patch to implement this. First patch in C, I hope it's fine.

https://github.com/micropython/micropython/pull/1376

Re: MicroPython round() Function

Posted: Sun Jul 12, 2015 5:00 pm
by dhylands
It looks like there are some compile failures on some of the platforms (if you click on the red-X you can see the full log - you'll need to scroll to find the errors).

I'd also recommend squashing this into a single commit.

Re: MicroPython round() Function

Posted: Tue Jun 28, 2016 8:29 am
by Iyassou
Hello,

I imagine you've found this out by now but for anyone else asking the same question and reading this thread with a more recent version of MicroPython (mine is 3.4.0), the function is in the math module, syntax is:

math.round(NumberToBeRounded, NumberOfDigitsAfterTheDecimalPointToBeRoundedTo)

Second argument is in other words the rounding precision.

Re: MicroPython round() Function

Posted: Thu Jun 30, 2016 3:52 am
by pythoncoder
I'm baffled by this thread. Perhaps someone can clarify, but on the Pyboard and Linux it seems to work fine here:

Code: Select all

MicroPython v1.8.1-39-gdb4addd on 2016-06-26; PYBv1.1 with STM32F405RG
Type "help()" for more information.
>>> round(1.2345,2)
1.23
>>> 
Unix build:

Code: Select all

[adminpete@axolotl]: ~
$ ./upython 
MicroPython v1.8.1-39-gdb4addd on 2016-06-14; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> round(3.14)
3
>>> round(3.14,2)
3.14
>>> round(3.14,1)
3.1
>>> round(1.23456,3)
1.235
>>> 
And it isn't in the math module: it's part of the Python language.

What is not supported in Micropython is having a negative second argument. In CPython this works as follows:

Code: Select all

[adminpete@axolotl]: ~
$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> round(1.23456,3)
1.235
>>> round(1234567, -1)
1234570
>>> 
I have raised this issue long ago and was informed that the limitation is by design, to keep the language 'micro'.

Apologies if I'm missing something here.

Re: MicroPython round() Function

Posted: Wed Jul 13, 2016 11:11 am
by Iyassou
pythoncoder you're absolutely right, you're missing nothing here. I made a horrible mistake in my post, thanks for correcting it.

Re: MicroPython round() Function

Posted: Wed Feb 01, 2017 12:44 pm
by legionnet
I use esp8266-20170108-v1.8.7 firmware.
I need to get the temperate and humidity from DHT22 (AM2301) with round.
But round() function does not always work.

My code:
ds.measure()
tem = round( float( ds.temperature() ), 1 )
hum = round( float( ds.humidity() ), 1 )

Output:
(2017, 2, 1, 15, 37, 48, 2, 32) 15 37 | 23 | temperature is 23.0 | humidity is 28.89999 | relay value is 0
(2017, 2, 1, 15, 37, 58, 2, 32) 15 37 | 23 | temperature is 23.0 | humidity is 28.89999 | relay value is 0
(2017, 2, 1, 15, 38, 8, 2, 32) 15 38 | 23 | temperature is 23.0 | humidity is 28.5 | relay value is 0
(2017, 2, 1, 15, 38, 19, 2, 32) 15 38 | 23 | temperature is 23.0 | humidity is 27.89999 | relay value is 0
(2017, 2, 1, 15, 38, 29, 2, 32) 15 38 | 23 | temperature is 23.0 | humidity is 28.6 | relay value is 0
(2017, 2, 1, 15, 38, 39, 2, 32) 15 38 | 23 | temperature is 23.0 | humidity is 29.0 | relay value is 0
(2017, 2, 1, 15, 38, 49, 2, 32) 15 38 | 23 | temperature is 23.0 | humidity is 29.0 | relay value is 0
(2017, 2, 1, 15, 39, 0, 2, 32) 15 38 | 23 | temperature is 23.0 | humidity is 29.0 | relay value is 0
(2017, 2, 1, 15, 39, 10, 2, 32) 15 39 | 23 | temperature is 23.0 | humidity is 29.1 | relay value is 0
(2017, 2, 1, 15, 39, 20, 2, 32) 15 39 | 23 | temperature is 23.0 | humidity is 29.0 | relay value is 0
(2017, 2, 1, 15, 39, 31, 2, 32) 15 39 | 23 | temperature is 23.0 | humidity is 29.0 | relay value is 0
(2017, 2, 1, 15, 39, 41, 2, 32) 15 39 | 23 | temperature is 23.0 | humidity is 29.2 | relay value is 0
(2017, 2, 1, 15, 39, 51, 2, 32) 15 39 | 23 | temperature is 23.0 | humidity is 29.0 | relay value is 0
(2017, 2, 1, 15, 40, 1, 2, 32) 15 40 | 23 | temperature is 23.0 | humidity is 27.89999 | relay value is 0
(2017, 2, 1, 15, 40, 12, 2, 32) 15 40 | 23 | temperature is 22.89999 | humidity is 28.5 | relay value is 1

Re: MicroPython round() Function

Posted: Wed Feb 01, 2017 4:18 pm
by dhylands
You need to differentiate the number from its printed representation.

Your round function is working fine. You have to keep in mind that you're using 32-bit floating point, and not all numbers in the base 2 system have an exact representation in base 10. Simple numbers in base 10 like 0.1 have no exact representation using a 32-bit float.

You can limit your print to 1 decimal point by doing something like:

Code: Select all

>>> print('{:.1f}'.format(28.899))
28.9
>>> print('%.1f' % 28.899)
28.9
A 32-bit float can store about 6 significant digits. The printing software, with no specific format defaults to 7 digits, this often causes the output to appear "off".

Re: MicroPython round() Function

Posted: Mon Apr 24, 2017 5:11 pm
by skimj
Dave's explanation and solution are correct.

Just to highlight the difference between the number and the display, take this example for which it wasn't obvious to me that the rounding function was working because the 2 least significant digits were the same (coincidentally):

Code: Select all

>>> round(68.79198,2)
68.78998
It wasn't obvious to my human brain that it was correct, but quite simiply:

Code: Select all

>>> 68.79
68.78998
The print/display omits insignificant 0's which causes round to appear to work as expected for some results (like pythoncoder's example) but not others:

Code: Select all

>>> round(1.2345,2)
1.23
>>> round(1.5432,2)
1.54
>>> round(6.2345,2)
6.23
>>> round(6.5432,2)
6.539999