How to convert Uint8List to Float32List to List in Flutter?

I'm using Dart's typed_data library together with flutter_bluetooth_serial. One of the latter's limitation is it can only read data in Uint8List format. However, I need to send a bunch of single-precision floating-point numbers (specifically from another microcontroller). I can send the data from the microcontroller to Flutter but the latter can't just decode the Uint8List well. I'm not sure if it is a bug in the library or I'm missing something in my code. Shown below is the snippet of the code which aims to convert intBytes to List<double>

Uint8List intBytes = Uint8List.fromList([63, 158, 184, 82,]); List<double> floatList = intBytes.buffer.asFloat32List().toList(); 

The intBytes variable represents a four-byte single-precision number (1.24...) which is declared with an array of 8-bit integers. However floatBytes can't seem to get the correct value from the said array even after viewing the buffer as a list of float. If I try to view the type of value from the first element with the following code

print(doubleList[0].runtimeType); 

It reads it as an int data type but I was expecting a double

2

1 Answer

From your comment:

the first element's value will be 396464455680; an integer value very far from the floating point value of 1.24...

396464455680 is a correct interpretation for a little-endian representation for a byte sequence 63, 158, 184, 82. You apparently assume that it will be interpreted as a big-endian single-precision floating point value, but IEEE-754 does not specify endianness. If you reverse the bytes, you will get 1.2400000095367432 on a little-endian system:

 Uint8List intBytes = Uint8List.fromList([63, 158, 184, 82].reversed.toList()); List<double> floatList = intBytes.buffer.asFloat32List(); print(floatList); 

(Incidentally, Float32List derives from List<double>, so you do not need the extra .toList() call.)

Alternatively, you can use ByteData.getFloat32 to parse bytes with a specified endianness:

 Uint8List intBytes = Uint8List.fromList([63, 158, 184, 82]); ByteData byteData = intBytes.buffer.asByteData(); List<double> floatList = [ for (var offset = 0; offset < intBytes.length; offset += 4) byteData.getFloat32(offset, Endian.big), ]; print(floatList); 

Note that using ByteData.getFloat32 would be more robust than reordering bytes yourself since it'd make your code agnostic to the endianness of the platform you're running on.

Regarding:

print(doubleList[0].runtimeType); 

It reads it as an int data type but I was expecting a double

Presuming that you mean floatList (doubleList is not defined in your example), if you run that code in the Dart VM, double should be printed.

If, however, you run that code in a web browser (e.g. with DartPad or with Flutter for the Web), int will be printed. As a simpler example, running:

 double d = 1.0; print(d.runtimeType); 

in DartPad also will print int. On the web, Dart transpiles to JavaScript, and for efficiency, Dart directly uses some JavaScript primitives. JavaScript does not distinguish between integer and floating-point types; all numbers are double-precision floating point values. It therefore isn't surprising that type information gets lost in the roundtrip.

4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like