Is there a bug in floating point arithmetic?

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
Jack-123
Posts: 5
Joined: Wed Sep 05, 2018 2:29 am

Is there a bug in floating point arithmetic?

Post by Jack-123 » Wed Sep 12, 2018 9:50 am

Hello everyone, I found that the micropython c function mp_obj_float_get(mp_const_obj_t o) may have a bug, the output result is a deviation of the actual value, but the result of the upper layer code Python is correct.
What should I do?
Thank you for reading.
-------------------------------------------- output print-----------------------------------------------------
test_data = 0.90
Python print:
0.9
C print:
0.900000 0.000000
-------------------------------

test_data = 10.90
Python print:
20.9
C print:
20.899999 0.000000
-------------------------------


-------------------------------------------- c code -----------------------------------------------------
mp_obj_t pyb_c_demo_callback_arg2(mp_obj_t self_in, mp_obj_t callback)
{
mp_obj_t aurry_1[6]={ mp_obj_new_float(0)};
mp_obj_t aurry_2[6]={ mp_obj_new_float(0)};
mp_obj_t list_1 = mp_obj_new_list(6, aurry_1);
mp_obj_t list_2 = mp_obj_new_list(6, aurry_2);

MP_STATE_PORT(pyb_c_demo_callback) = callback;

if (callback != mp_const_none)
{
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0)
{
mp_call_function_2(MP_STATE_PORT(pyb_c_demo_callback),list_1,list_2);
nlr_pop();
}
else
{
// Uncaught exception; disable the callback so it doesn't run again.
printf("uncaught exception in \n");
mp_obj_print_exception(&pyb_c_demo_print, MP_OBJ_FROM_PTR(nlr.ret_val));
}
}
else
{
printf("pyb_c_demo_callback) == mp_const_none");
}

mp_obj_t *list_items;
size_t path_num = 6;
mp_obj_list_get(list_2, &path_num, &list_items);

printf("%f %f\n",mp_obj_float_get(list_items[0]),mp_obj_float_get(list_items[1]));

return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_c_demo_callback_arg2_obj, pyb_c_demo_callback_arg2);

-------------------------------------------- Python code -----------------------------------------------------
def test_callback_arg2(data1, data2):
""" """
print("TEST \n")
print("Python print: ")
test_data = 0.90
data = data2[0] = data2[0] + test_data
print(data)
print("C print: ")

if __name__ == "__main__":

c_demo = pyb.cdemo()
c_demo.callbackarg2(test_callback_arg2)

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

Re: Is there a bug in floating point arithmetic?

Post by dhylands » Wed Sep 12, 2018 5:38 pm

You've discovered a difference in how the floating point number is printed.

When you do a print of a floating point number in python, then it calls this code: https://github.com/micropython/micropyt ... oat.c#L123

which, on the pyboard, is the equivalent of printf("%.7g", val);

I did a quick and dirty test, and what I see on the pyboard for this code:

Code: Select all

    double val = 20.9f;
    printf("%%f format = '%f'\n", val);
    printf("%%.7g format = '%.7g'\n", val);
is this output:

Code: Select all

%f format = '20.899999'
%.7g format = '20.9'
which agrees with the code that you presented.

This issue that you've run into is that floating point numbers are internally represented using base 2, and when you print them you're printing them in base 10. Many numbers in base 10 do not have an exact representation in base 2, and 20.9 happens to be one of those numbers.

If I run the following code on Python3 (which I believe uses 64-bit floats versus the 32-bit floats used on the pyboard) we can see that even there, a number like 20.9 doesn't have an exact representation in base 2:

Code: Select all

Python 3.6.5 (default, Apr  1 2018, 05:46:30) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 20.9
>>> print('%.10g' % x)
20.9
>>> print('%.20g' % x)
20.899999999999998579
>>> print('%.30g' % x)
20.8999999999999985789145284798
The python3 documentation gives some good information as well: https://docs.python.org/3/tutorial/floatingpoint.html

You should read: https://floating-point-gui.de/ and https://docs.oracle.com/cd/E19957-01/80 ... dberg.html to understand why these little differences crop up and how your code should deal with them.

Jack-123
Posts: 5
Joined: Wed Sep 05, 2018 2:29 am

Re: Is there a bug in floating point arithmetic?

Post by Jack-123 » Thu Sep 13, 2018 5:21 am

Thank you very much, Dhylands's answer.

Post Reply