2013-10-29 111 views
0

我需要解碼編碼爲IEEE double(來自iOS NSTimeInterval)並存儲在8字節數組中的時間戳,以便我可以使用ctime以可讀的格式打印出時間戳。這在大多數系統中是微不足道的,但不是我的。在不支持雙精度的C編譯器上將64位雙精度浮點數據轉換爲Uint32

Example: on iOS side 

uint8_t data[8]; 
double x = 3.14; 
memcpy(data,&x,8); 

我在MSP430F5438A上運行,我需要使用COFF ABI鏈接第三方零件庫。如果您使用COFF ABI,則TI的Code Composer不支持64位浮點類型(IEEE雙精度型)。它對待doublefloat(即單精度)相同。

這些不起作用。

uint8_t data[8]; 
double x; 
memcpy(&x,data,8); 

x = *(double*)data; 

union { 
    uint8_t data[8]; 
    double d; 
} x; 
memcpy(x.data,data,8); 

我只是得到亂碼,因爲double只有4使用的Code Composer字節。我需要一種方法將uint8_t[8]數據(這是一個合法的IEEE雙精度值)直接轉換爲整數值。

回答

1

這會將積分double轉換爲精確的uint32_t(只要沒有溢出,最大爲2^32-1)。如果雙倍是南或Inf,這將不起作用,但這不太可能。

static unsigned long ConvertDoubleToULong(void* d) 
{ 
unsigned long long x; 
unsigned long long sign ; 
long exponent; 
unsigned long long mantissa; 

memcpy(&x,d,8); 

// IEEE binary64 format (unsupported) 
sign  = (x >> 63) & 1; // 1 bit 
exponent = ((x >> 52) & 0x7FF); // 11 bits 
mantissa = (x >> 0) & 0x000FFFFFFFFFFFFFULL; // 52 bits 
exponent -= 1023; 

mantissa |=   0x0010000000000000ULL; // add implicit 1 

int rshift = 52 - exponent; 
if (rshift > 52) { 
    x = 0; 
} else if (rshift >=0) { 
    x = mantissa >> rshift; 
} else { 
    x = 0x7FFFFFFF; 
} 
if (sign == 0) { 
    return x; 
} else { 
    return -x; 
} 
} 
+1

NSTimeInterval不太可能有精確的整數值。它以秒爲單位,亞毫秒精度。精確的精確度沒有被指定,所以你不能用一個已知的值乘以它來縮放到一個確切的整數值。它看起來像這個代碼將趨於零。 –

+0

@EricPostpischil - 是的,我知道。但'time_t'是整數,所以我可以扔掉小數部分。我不需要1秒的準確性。 –

相關問題