我正在尝试将浮点值从我的程序转储到bin文件。由于我不能使用任何stdlib函数,我正在考虑将char写入char到一个大的char数组,我将我的测试应用程序转储到一个文件中。
就像
float a=3132.000001;
我将把它转储到4个字节的char数组中。
代码示例如下: -
if((a < 1.0) && (a > 1.0) || (a > -1.0 && a < 0.0))
a = a*1000000 // 6 bit fraction part.
请你帮助我以更好的方式写这篇文章。
答案 0 :(得分:4)
假设您打算在同一架构上将其读回同一程序(没有字节序问题),只需直接写出数字:
fwrite(&a, sizeof(a), 1, f);
或将其与memcpy一起复制到您的中间缓冲区:
memcpy(bufp, &a, sizeof(a));
bufp += sizeof(a);
如果你必须处理字节序问题,你可能会偷偷摸摸。将浮点数转换为long,并使用htonl:
assert(sizeof(float) == sizeof(long)); // Just to be sure
long n = htonl(*(long*)&a);
memcpy(bufp, &n, sizeof(n));
bufp += sizeof(n);
回读:
assert(sizeof(float) == sizeof(long)); // Just to be sure
long n;
memcpy(&n, bufp, sizeof(n));
n = ntohl(n);
a = *(float*)n;
bufp += sizeof(n);
答案 1 :(得分:1)
使用frexp
。
int32_t exponent, mantissa;
mantissa = frexp( a, &exponent ) / FLT_EPSILON;
在尾数中捕获符号。这应该正确处理非正规,但不能处理无穷大或NaN。
写exponent
和mantissa
必然需要超过4个字节,因为隐式尾数位是显式的。如果你想把浮点数写成原始数据,问题根本不是关于浮点数,而是处理原始数据和字节顺序。
另一方面,请使用ldexp
。
如果您可以使用标准库,printf
只有一个格式说明符:%a
。但也许您认为frexp
也是标准库。不清楚。
答案 2 :(得分:0)
如果您不担心读者和作者之间的平台差异:
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
...
union float_bytes {
float val;
uint8_t a[sizeof(float)]; // This type can be unsigned char if you don't have stdint.h
};
size_t float_write(FILE * outf, float f) {
union float_bytes fb = { .val = f };
return fwrite(fb.a, sizeof(float), outf);
}
将浮点数转换为字节数组的方法较短,但它们涉及更多的类型转换,更难以阅读。执行此操作的其他方法可能不会使编译代码更快或更小(尽管联合将使调试代码更大)。
如果您尝试以独立于平台的方式存储浮点数,那么最简单的方法是将其存储为字符串(在。之后有大量数字)。更难的是选择一个浮点位布局来使用,并在读/写时将所有浮点数转换为该格式。可能只是选择一定宽度的IEEE浮点和某个端点并坚持下去。