2010-04-26 194 views
2

我正在尝试将我的程序中的浮点值转储到bin文件。由于我不能使用任何stdlib函数,我正在考虑通过char将它字符写入一个大的char数组中,我将其在测试应用程序中倾倒到一个文件中。如何准确地将浮点值写入bin文件

这就像

float a=3132.000001; 

我将在4个字节被倾倒到这个字符数组。

代码的例子是: -

if((a < 1.0) && (a > 1.0) || (a > -1.0 && a < 0.0)) 
    a = a*1000000 // 6 bit fraction part. 

能否请你帮我在一个更好的方式书面方式这一点。

回答

4

假设你打算读它放回同一架构(无排列顺序问题)相同的程序,只写数出直接:

fwrite(&a, sizeof(a), 1, f); 

或memcpy的复制到您的中间缓冲:

memcpy(bufp, &a, sizeof(a)); 
bufp += sizeof(a); 

如果你必须处理排序问题,你可能会鬼鬼祟祟。铸造浮子长,并使用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

Marcelo,你可以扩展你的答案来解决排序问题吗?提前致谢。 – 2010-04-26 04:31:07

1

使用frexp

int32_t exponent, mantissa; 
mantissa = frexp(a, &exponent)/FLT_EPSILON; 

该标志被捕获在尾数。这应该正确处理非正常,但不是无限或NaN。

写入exponentmantissa将必然需要超过4个字节,因为隐式尾数位是明确的。如果你想把float写成原始数据,这个问题不是关于浮动,而是处理原始数据和字节顺序。

另一方面,使用ldexp

如果您可以使用标准库,printf只有格式说明符:%a。但也许你认为frexp也是标准库。不清楚。

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); 
} 

有更短的方式把一个浮动成字节数组,但它们涉及更多类型转换,并且更难读。其他的做法可能不会使速度更快或更小的编译代码(尽管联合会使调试代码更大)。

如果您尝试以独立于平台的方式存储浮动内容,那么最简单的方法是将其存储为字符串(后面带有大量数字)。更困难的是选择一个浮点位布局来使用和转换所有的浮点数到/从这个格式读/写它们。可能只是选择一定宽度和特定的endian的IEEE浮点,并坚持这一点。