Floating point to 16 bit Twos Complement Binary, Python

匆匆过客 提交于 2019-12-23 06:28:23

问题


so I think questions like this have been asked before but I'm having quite a bit of trouble getting this implemented.

I'm dealing with CSV files that contain floating points between -1 and 1. All of these floating points have to be converted to 16 bit 2s complement without the leading '0b'. From there, I will convert that number to a string representation of the 2s complement, and all of those from the CSV will be written will be written to a .dat file with no space in between. So for example, if I read in the CSV file and it has two entries [0.006534, -.1232], I will convert each entry to their respective 2s complement and write them one after another onto a .dat file.

The problem is I'm getting stuck in my code on how to convert the floating point to a 16 bit 2s complement. I've been looking at other posts like this and I've been told to use the .float() function but I've had no luck.

Can someone help me write a script that will take in a floating point number, and return the 16 bit 2s complement string of it? It has to be exactly 16 bits because I'm dealing with the MIT 16 standard.

I am using python 3.4 btw


回答1:


To answer the question in the title: to convert a Python float to IEEE 754 half-precision binary floating-point format, you could use binary16:

>>> from binary16 import binary16
>>> binary16(0.006534)
b'\xb0\x1e'
>>> binary16(-.1232)
b'\xe2\xaf'

numpy produces similar results:

>>> import numpy as np
>>> np.array([0.006534, -.1232], np.float16).tostring()
b'\xb1\x1e\xe3\xaf'
>>> np.array([0.006534, -.1232], '>f2').tostring() # big-endian
b'\x1e\xb1\xaf\xe3'

My goal was to save the amplitudes as the ecg mit signal format 16
..snip..
the input is a .CSV file containing the f.p. values of the amplitude from a .WAV file (which is the recording of an ECG).

You could read the wav file directly and write the corresponding 16-bit two's complement amplitudes in little-endian byte order where any unused high-order bits are sign-extended from the most significant bit ('<h' struct format):

#!/usr/bin/env python3
import wave

with wave.open('ecg.wav') as wavfile, open('ecg.mit16', 'wb') as output_file:
    assert wavfile.getnchannels() == 1 # mono
    assert wavfile.getsampwidth() == 2 # 16bit
    output_file.writelines(iter(lambda: wavfile.readframes(4096), b''))

There is a bug in Python 3 that .readframes() returns str instead of bytes sometimes. To workaround it, use if not data test that works on both empty str and bytes:

#!/usr/bin/env python3
import wave

with wave.open('ecg.wav') as wavfile, open('ecg.mit16', 'wb') as output_file:
    assert wavfile.getnchannels() == 1 # mono
    assert wavfile.getsampwidth() == 2 # 16bit
    while True:
        data = wavfile.readframes(4096)
        if not data:
            break
        output_file.write(data)


来源:https://stackoverflow.com/questions/31464022/floating-point-to-16-bit-twos-complement-binary-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!