Is there a bug in floating point arithmetic?
Posted: 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)
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)