浮点到 16 位二进制补码二进制,Python

Posted

技术标签:

【中文标题】浮点到 16 位二进制补码二进制,Python【英文标题】:Floating point to 16 bit Twos Complement Binary, Python 【发布时间】:2015-07-16 20:34:13 【问题描述】:

所以我认为以前有人问过这样的问题,但我在实现这一点时遇到了很多麻烦。

我正在处理包含 -1 和 1 之间的浮点数的 CSV 文件。所有这些浮点数都必须转换为没有前导“0b”的 16 位 2s 补码。从那里,我将该数字转换为 2s 补码的字符串表示形式,所有来自 CSV 的数字都将被写入一个 .dat 文件,中间没有空格。例如,如果我读入 CSV 文件并且它有两个条目 [0.006534, -.1232],我会将每个条目转换为它们各自的 2s 补码,并将它们一个接一个地写入 .dat 文件。

问题是我在如何将浮点数转换为 16 位 2s 补码的代码中陷入困境。我一直在看this 之类的其他帖子,有人告诉我使用 .float() 函数,但我没有运气。

有人可以帮我写一个脚本来接受浮点数,并返回它的 16 位 2s 补码字符串吗?它必须正好是 16 位,因为我正在处理 MIT 16 标准。

我正在使用 python 3.4 顺便说一句

【问题讨论】:

“16 位 2s 补码”描述了 16 位整数类型。它不能用于表示小数值。您的意思是要将值从 [-1…1] 缩放到 [-32768…32767]? 嗯,我不完全确定。让我问问我的主管。 我正在处理设备上记录的心电图数据,转换为 WAV,提取十进制值。我想我需要做更多的研究 这就是我得到的“每个样本都由一个 16 位二进制补码幅度表示,首先存储最低有效字节。任何未使用的高位都从最高有效位进行符号扩展。格式用于 MIT-BIH 和 AHA 数据库分发的 9 轨磁带是格式 16,在逻辑 EOF 之后添加了逻辑 EOF(八进制 0100000)和空填充。” @J.F.Sebastian 我很抱歉在 cmets 中回复。最初,输入是一个包含 f.p. 的 .CSV 文件。 .WAV 文件(心电图记录)中的振幅值。所以我有一个 .WAV 和一个 .CSV 文件。首先,我尝试使用 physionet 提供的 WAV2MIT.c 文件,但遇到了一些问题。但是,在我最后的评论中,我说明了我是如何转换 f.p. 的。值到正确的 2s 补码格式。 【参考方案1】:

要回答标题中的问题:要将 Python float 转换为 IEEE 754 half-precision binary floating-point format,您可以使用 binary16

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

numpy 产生类似的结果:

>>> 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'

我的目标是将幅度保存为 ecg mit 信号格式 16 ..剪辑.. 输入是一个包含 f.p. 的 .CSV 文件。 .WAV 文件(心电图记录)中的振幅值。

您可以直接读取 wav 文件并以 little-endian 字节顺序写入相应的 16 位二进制补码幅度,其中任何未使用的高位从最高有效位进行符号扩展('<h' 结构格式):

#!/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''))

有一个bug in Python 3 有时.readframes() 返回str 而不是bytes。要解决此问题,请使用适用于空 strbytesif not data 测试:

#!/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)

【讨论】:

我在尝试运行您的代码时收到此错误。 C:\matlab2>py test.py Traceback(最近一次调用):文件“test.py”,第 7 行,在 output_file.writelines(iter(lambda: wavfile.readframes(4096), 'b') ) TypeError: 'str' 不支持缓冲区接口 @AbbasDharamsey:这是 Python 中的一个错误。我已经发布了一个解决方法。 谢谢@J.F.塞巴斯蒂安。这几乎是完美的,除了没有解调。我有一个前实习生编写的解调 .exe,一切正常,但感谢您帮助我查看是否可以轻松地从 .wav 文件中获取 ECG 数据:) 我会将解调应用程序发布到 github 但它是不是我的,它归我​​公司所有 :( @AbbasDharamsey:你的意思是你的数据是第三种情况(AM 信号)from this description? Does wav2mit work for you?

以上是关于浮点到 16 位二进制补码二进制,Python的主要内容,如果未能解决你的问题,请参考以下文章

16位二进制补码有符号整数信号数据的位平面分解?

整形和浮点型数据存储详解

浮点型在计算机内的存储方式

关于原码,反码和补码

第12章 整数运算

原码反码补码&浮点类型的存储