2013-10-29 88 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秒的准确性。 –

相关问题