How to reconstruct floats stored in PoolByteArray?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By xlxs

I’m sending UDP packets to a PC that runs a Godot app. The packets contain 4 byte floats. I’m using PacketPeerUDP to receive the packets. The problem is that, PacketPeerUDP has only a method (get_packet()) to read packets as bytes and not as floats… How to reconstruct the the packets as floats? (I don’t want to use get_var() because it introduces extra overhead to the sender)
Any ideas are highly appreciated.

:bust_in_silhouette: Reply From: Zylann

Maybe you can use a StreamPeerBuffer? StreamPeerBuffer — Godot Engine (stable) documentation in English

The actual implementation could be something like this:

var spb = StreamPeerBuffer.new()
spb.data_array = pkt
var single_float = spb.get_float()

programagor | 2020-09-03 04:54

:bust_in_silhouette: Reply From: programagor

I had to resort to brute-forcing the solution, according to the IEEE754 specifications.

func bin2float(pkt:PoolByteArray) -> float:
#Convert packet to an array of bools
var arr:Array=[]
for byte in pkt:
    for _i in range(0,8):
        arr.append(byte%2)
        byte/=2
        
#Extract sign
var r_sign:int
if arr[31]==1:
    r_sign=-1
else:
    r_sign=1

#Extract exponent
var r_exp:int=0
for i in range(30,22,-1):
    r_exp*=2
    r_exp+=arr[i]
r_exp-=127

#Extract mantissa
var r_mant:float=0
for i in range(0,23):
    r_mant+=arr[i]
    r_mant/=2
r_mant+=1

return r_sign*pow(2,r_exp)*r_mant

Of course this is terribly slow, and a real native solution would still be greatly appreciated, but this works in the meantime.