struct on WiPy gives different output than on PC

  • I'm sending serial messages that consist of float values encoded using struct between my WiPy and PC (python 2.7). When I encode a decimal value, like 3.4, on the WiPy and then send it to the PC and decode it I get 3.4000000953674316. I noticed that the output of struct.pack('<d',3.4) is slightly different on the WiPy and on the PC.

    Code on WiPy:

    x_wipy= struct.pack('d', 3.4)      #encode value
    print(binascii.hexlify(x_wipy))    #display encoding
    >>> b'0000004033330b40'

    Code on PC (python 2.7):

    x_pc = struct.pack('d', 3.4)     #encode value
    print(binascii.hexlify(x_pc))    #display encoding
    >>> 3333333333330b40

    Does anyone know why they differ? Could it be different versions of python?

    Other observations:

    • WiPy decodes both x_wipy and x_pc correctly to 3.4
    • PC decodes x_pc to 3.4 and x_wipy to 3.4000000953674316
    • WiPy returns bytes, PC returns str -> this is due to different python versions

  • @alexpul Indeed, but both pack to the same bytes object.

    >>> struct.pack("f", 3.4)
    >>> struct.unpack("f", b'\x9a\x99Y@')


    >>> struct.pack("f", 3.4)

  • Thanks for the great reply @robert-hh!

    For any other readers that may be having similar problems: I'm sending the encoded data from the wipy to my PC and I found that even if I encoded it using a single precision float ('f') the value still showed in python as a 64 bit number (hence the really long decimal value). I found that if I forced python to see the number as 32 bit using numpy.float32(x_wipy) then the decimal was correctly represented.

  • @alexpul Micropython does supports only 32 bit floats with, giving a ~7 digit precision, and 3.4 being not a binary fraction cannot be encoded w/o precision loss into a float. That is different for numbers, which can be represented as binary fraction, like 3.5. PC Python uses 64 bit floats.
    So what you see are rounding errors in different occurences.

Log in to reply

Pycom on Twitter