Array of floats

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
pauljohnleonard
Posts: 2
Joined: Tue Jul 29, 2014 12:15 pm

Array of floats

Post by pauljohnleonard » Tue Jul 29, 2014 12:19 pm

Trying to run some DSP code but . . .

>>> array.array('f',[0])
Traceback (most recent call last):
File "<stdin>", line 0, in <module>
ValueError: bad typecode

Does this mean I can not create an array of floats?

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Array of floats

Post by stijn » Tue Jul 29, 2014 1:04 pm

seems like so, this is the typecode parsing in binary.c (function mp_binary_get_size) and it doesn't have 'f':

Code: Select all

            switch (val_type) {
                case BYTEARRAY_TYPECODE:
                case 'b': case 'B':
                    align = size = 1; break;
                case 'h': case 'H':
                    align = size = sizeof(short); break;
                case 'i': case 'I':
                    align = size = sizeof(int); break;
                case 'l': case 'L':
                    align = size = sizeof(long); break;
                case 'q': case 'Q':
                    // TODO: This is for x86
                    align = sizeof(int); size = sizeof(long long); break;
                case 'P': case 'O': case 'S':
                    align = size = sizeof(void*); break;
I'm not sure this is by design or just forotten because mp_binary_get_val_array on the other hand does have 'f' and 'd'.
So adding this case to mp_binary_get_size:

Code: Select all

#if MICROPY_PY_BUILTINS_FLOAT
                case 'f':
                    align = size = sizeof(float); break;
                case 'd':
                    align = size = sizeof(double); break;
#endif
makes your code accepted and working at first sight.
I'd suggest you add this, build the code and see if it works out.
Then to get feedback, create a pull request for it (or eventually if it doesn't work at all create a bug report)

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

Re: Array of floats

Post by dhylands » Tue Jul 29, 2014 5:06 pm

If you'd like to go through the process of submitting a fix, I'm more than happy to guide you along the way.

If not, I'm also more than happy to do up a PR for this.

Let me know.

pauljohnleonard
Posts: 2
Joined: Tue Jul 29, 2014 12:15 pm

Re: Array of floats

Post by pauljohnleonard » Wed Aug 27, 2014 12:18 pm

Sorry about the delay (been busy/on leave).

stijn's fix seems to help but still some problems (does not convert my int on assignment).

Using the unix build . . . .

Code: Select all

>>> from array import *
>>> x=array('f',[0.0,1.0,2.0])
>>> x
array('f', [0.0, 1.0, 2.0])
>>> x[1]=3.0
>>> x
array('f', [0.0, 3.0, 2.0])
>>> x[1]=x[0]*4
>>> x
array('f', [0.0, 0.0, 2.0])
>>> x[1]=x[2]*4
>>> x
array('f', [0.0, 8.0, 2.0])
>>> x[1]=4
micropython: ../py/objfloat.c:132: mp_obj_float_get: Assertion `(MP_OBJ_IS_OBJ(self_in) && (((mp_obj_base_t*)(self_in))->type == (&mp_type_float)))' failed.
Aborted (core dumped)

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

Re: Array of floats

Post by dhylands » Wed Aug 27, 2014 3:12 pm

It looks like this code: https://github.com/micropython/micropyt ... ary.c#L240

Code: Select all

#if MICROPY_PY_BUILTINS_FLOAT
        case 'f':
            ((float*)p)[index] = mp_obj_float_get(val_in);
            break;
        case 'd':
            ((double*)p)[index] = mp_obj_float_get(val_in);
            break;
#endif
should be calling mp_obj_get_float rather than mp_obj_float_get.

mp_obj_float_get assumes that the object is a float and returns its value.
mp_obj_get_float knows how to convert various types of objects into a float.

When you add your changes, you should add some tests as well (probably in tests/basics/test1.py)

You can run the tests using:

Code: Select all

cd tests
./run-tests basics/test1.py
To run all of the tests, run run-tests with no arguments.

Post Reply