Skip to content

Commit 0b3014c

Browse files
dooglepfalcon
authored andcommitted
py: Add support for floats in mp_binary_{get,set}_val()
- This then provides support for floats in the struct package
1 parent a5efcd4 commit 0b3014c

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

py/binary.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,14 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
194194
} else if (val_type == 'S') {
195195
const char *s_val = (const char*)(mp_uint_t)val;
196196
return mp_obj_new_str(s_val, strlen(s_val), false);
197+
#if MICROPY_PY_BUILTINS_FLOAT
198+
} else if (val_type == 'f') {
199+
union { uint32_t i; float f; } fpu = {val};
200+
return mp_obj_new_float(fpu.f);
201+
} else if (val_type == 'd') {
202+
union { uint64_t i; double f; } fpu = {val};
203+
return mp_obj_new_float(fpu.f);
204+
#endif
197205
} else if (is_signed(val_type)) {
198206
if ((long long)MP_SMALL_INT_MIN <= val && val <= (long long)MP_SMALL_INT_MAX) {
199207
return mp_obj_new_int((mp_int_t)val);
@@ -249,6 +257,27 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
249257
case 'O':
250258
val = (mp_uint_t)val_in;
251259
break;
260+
#if MICROPY_PY_BUILTINS_FLOAT
261+
case 'f': {
262+
union { uint32_t i; float f; } fp_sp;
263+
fp_sp.f = mp_obj_get_float(val_in);
264+
val = fp_sp.i;
265+
break;
266+
}
267+
case 'd': {
268+
union { uint64_t i64; uint32_t i32[2]; double f; } fp_dp;
269+
fp_dp.f = mp_obj_get_float(val_in);
270+
if (BYTES_PER_WORD == 8) {
271+
val = fp_dp.i64;
272+
} else {
273+
int be = struct_type == '>';
274+
mp_binary_set_int(sizeof(uint32_t), be, p, fp_dp.i32[MP_ENDIANNESS_BIG ^ be]);
275+
p += sizeof(uint32_t);
276+
val = fp_dp.i32[MP_ENDIANNESS_LITTLE ^ be];
277+
}
278+
break;
279+
}
280+
#endif
252281
default:
253282
// we handle large ints here by calling the truncated accessor
254283
if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) {

tests/float/float_struct.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# test struct package with floats
2+
3+
import struct
4+
5+
i = 1. + 1/2
6+
# TODO: it looks like '=' format modifier is not yet supported
7+
# for fmt in ('f', 'd', '>f', '>d', '<f', '<d', '=f', '=d'):
8+
for fmt in ('f', 'd', '>f', '>d', '<f', '<d'):
9+
x = struct.pack(fmt, i)
10+
v = struct.unpack(fmt, x)[0]
11+
print('%2s: %.17f - %s' % (fmt, v, (i == v) and 'passed' or 'failed'))
12+

0 commit comments

Comments
 (0)