2010-04-26 195 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浮點,並堅持這一點。