MicroPython round() Function

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
John Roach
Posts: 1
Joined: Sun Jul 12, 2015 4:01 am

MicroPython round() Function

Post by John Roach » Sun Jul 12, 2015 4:21 am

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.

Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: MicroPython round() Function

Post by Turbinenreiter » Sun Jul 12, 2015 10:35 am

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

Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: MicroPython round() Function

Post by Turbinenreiter » Sun Jul 12, 2015 11:17 am

I committed a patch to implement this. First patch in C, I hope it's fine.

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

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: MicroPython round() Function

Post by dhylands » Sun Jul 12, 2015 5:00 pm

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.

Iyassou
Posts: 42
Joined: Sun Jun 26, 2016 9:15 am

Re: MicroPython round() Function

Post by Iyassou » Tue Jun 28, 2016 8:29 am

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.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: MicroPython round() Function

Post by pythoncoder » Thu Jun 30, 2016 3:52 am

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.
Peter Hinch
Index to my micropython libraries.

Iyassou
Posts: 42
Joined: Sun Jun 26, 2016 9:15 am

Re: MicroPython round() Function

Post by Iyassou » Wed Jul 13, 2016 11:11 am

pythoncoder you're absolutely right, you're missing nothing here. I made a horrible mistake in my post, thanks for correcting it.

legionnet
Posts: 2
Joined: Wed Feb 01, 2017 12:35 pm

Re: MicroPython round() Function

Post by legionnet » Wed Feb 01, 2017 12:44 pm

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

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: MicroPython round() Function

Post by dhylands » Wed Feb 01, 2017 4:18 pm

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".

skimj
Posts: 3
Joined: Thu Mar 09, 2017 5:25 am

Re: MicroPython round() Function

Post by skimj » Mon Apr 24, 2017 5:11 pm

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

Post Reply