解释 C 语言中的浮点数据
Interpreting float data in C
我正在调试缓冲区中出现的数据获得错误值的问题。我正在将缓冲区 ( u8
) 类型从内核驱动程序发送到 HAL。在 HAL 中,有一个Uint16
缓冲区,它从此缓冲区接收值。
//Code to copy BUFFLEN contents from u8 data[BUFFLEN] into uint16_tData ;
uint16_t uint16_tData[BUFFLEN / 2];
float floatdata[BUFFLEN / 2];
我使用此类型转换从uint16_tData
缓冲区获取浮点值:
floatdata[index] = (*((float *)((void *)&uint16_tData[index1];
现在我的问题:如何解释驻留在floatdata
数组中的数据?假设我有数据floatdata[0] = 53640;
我如何在floatdata[0]
中解释这个半字节中的浮点数据
注意来自 u8 的 4 个字节 -->数组 uint16_tData 的 2 个元素 -->数组浮点数据的一个元素。
我想通过一个例子来了解:
从驱动程序传输的值为:
u8 val1 = 206
u8 val2 = 208
u8 val3 = 120
u8 val4 = 68
在 HAL 中,转换将如何进行,我将在此处获得哪些值?
uint16_tData[0] = ?
uint16_tData[1] = ?
以及如何将数据解释为floatdata
中的浮点数?
floatdata[0] = ?
这样做?
我想你想要这个:
float *floatdata;
floatdata = (float *)uint16_tData;
// Now use floatdata[index] ...
一次铸造一个物品是愚蠢的。 从uint16_t到浮点的铸造更加愚蠢,最好将其保留为uint8_t(字节),他似乎在其中,或者至少使用uint32_t作为中间。
有什么阻止你这样做的吗? 你能想到如何重新设计你的代码,这样你就可以完全避免处理这些问题吗?
根据我对你的问题的理解,这是你想要的吗
float f ;
uint8_t u8arr[4]={206,208,120,68};
uint16_t arr[2];
memcpy(&arr[0],u8arr,2);
memcpy(&arr[1],u8arr+2,2);
memcpy(&f,arr,4);
uint16
"由"2 u8
组成,单精度float
为 32 位(4 u8 或 2 uint16),但它们如何"转换"取决于处理这些数据的代码,特别是"发送"的含义(来自内核驱动程序)以及"接收"的代码如何期望数据。我承认我对这个话题一无所知,我现在无法检查和研究它,但我怀疑你有一个字节序问题:你的数据完全具有"意义",而不是单个八位字节,但你把它们放在内存中顺序错误。
基本上,你有一个包含你的八位字节的缓冲区,比如
A B C D
u8 u8 u8 u8 4 u8 arr element (arr[0], arr[1] ...)
____/ ____/
uint16 uint16 2 uint16 arr element (arr[0] and arr[1])
按照此内存地址递增顺序。如果您希望将A B
读取为"正确"的uint16数字,则必须在内存中对其进行"排序",以便匹配处理器的字节序:例如,如果您希望将数字A*8 + B
在一个小字节序CPU上,则必须以相反的顺序在内存中写入两个u8:
B A D C
我怀疑 HAL 使用 uint16 只是为了存储数据,而不是将它们解释为 16 位数字,所以这里的字节序不是问题。但是一旦你想从内存中的 4 个 u8(或 2 uint16)获得正确的"浮点数":你必须将 u8 按正确的顺序排列。
如果你想让你的u8被解释为通过铸件浮动,你首先必须将它们放在一个小端机器中,
例如 address of arr8[0] and arr16[0]
/
D C B A
u8 u8 u8 u8 4 u8 arr element (arr8[0], arr8[1] ...)
____/ ____/
uint16 uint16 2 uint16 arr element (arr16[0] and arr16[1])
然后,如果你在 litte endian 机器上将这些八位字节"读取"为浮点数,你就有了正确的"浮点数"。
因此,由您来正确排序您的 u8,知道它们将被解释为"宽度"大于一个八位字节的另一种类型。可移植代码应使用正确的方法为具有不同字节序的处理器正确编译。
另请参阅此维基百科文章
我对 HAL/DX 不友好,所以这可能是一个愚蠢的笔记
但是您确定您的浮点数是 16 位而不是 32 位吗?
- 如果没有,那么每个 2 位浮点数需要 2x16 位 uint,并且错误就在那里。
-
如果是,请进一步阅读
- 转到此处: http://msdn.microsoft.com/en-us/library/Windows/desktop/cc308050(v=vs.85).aspx#alpha_16_bit
- 查找 16 位规则
- 查找位计数和位置(符号,exp,尾蒂萨)
好的,现在你的问题是什么:
-
你有 uint 缓冲区,但将浮点存储在里面?
-
在这种情况下,只需执行以下操作:
float16 *p=(float16*)uint16_tData;
- 并使用 p 而不是 uint16_tData
你有 uint -
缓冲区,里面存储了 uint 值?
- 这意味着您需要将 uint 转换为浮点 数
- 使用内部 = 运算符(如果存在)
- 如果没有,请编写自己的转换
- 您可以忽略 uint 的符号
- 将 exp 设置为 0 (2^0)
- 将尾数设置为 uint 值
- 截断未拟合的位
- 只需向右移动/inc指数,直到uint的MSB适合尾数
- 将所有位移/和/或放在它们的位置(见上面的链接)
您有浮点值,需要将它们作为 uint 存储在 uint 中
- 所以简单地向后做上一点
- 提取指数,尾数,忽略符号或使用2'os补码
- 将尾数向左移动指数(如果为正),否则向右移位 -指数
- 仅此而已。
请注意,在某些平台/编译器/数据类型上,位移也可以插入来自进位或数字另一侧的位移。在这种情况下,结果与位掩码。
不要忘记应用指数偏差!!
希望它有所帮助
- 是否可以用类似C/C++(或任何语言)的语言,从作为用户输入的字符串或文件中创建用户定义的数据类型
- C++ 将字符串数据包转换为 iphdr语言 - 字符串数据包的格式应该是什么?
- 为什么像C++和Java这样的语言有一个内置的LinkedList数据结构
- LLVM:如何在运行时跟踪非类型语言的 Value* 的数据类型?
- 如何将数据发送到另一个过程(仅在C 语言级别上)
- 我如何使用GO语言读取可能是两种不同数据类型之一的HDF5属性
- 实时在语言之间流水线传输或以其他方式传输数据
- 自然语言中解析树的数据结构C/C
- 使用C++或任何windows脚本语言格式化文本数据
- c语言 - fprintf() 函数无法将数据保存到文件中;后面必须跟着 fflush() 函数吗?
- 解释 C 语言中的浮点数据
- Java 编程语言中的数据类型如何映射到本机编程语言(如 C 和 C++)中的数据类型
- 如何在 C 语言中写入特定地址的数据
- r语言 - 如何直接在数据库服务器上运行C++进程以避免传输数据集
- 如何在Windows和Linux上用C、c++语言从tcp/ip端口发送数据和获取数据
- 用C语言对蓝牙数据包进行分析
- Qt Creator语言 - 写入串行接收数据到UI
- 将数据存储在memcache中以供不同语言访问
- 语言和数据库适合数据驱动的游戏,如足球经理
- 在C语言中从文本文件中读取特定的数据列