簡體   English   中英

在不支持雙精度的C編譯器上將64位雙精度浮點數據轉換為Uint32

[英]Convert 64-bit double precision floating point data to Uint32 on a C compiler that doesn't support double precision

我需要解碼一個編碼為IEEE double的時間戳(從iOS NSTimeInterval )並存儲在8字節數組中,以便可以使用ctime以人類可讀的格式打印該時間戳。 這在大多數系統上都是微不足道的,但在我的系統上卻並非如此。

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 double)。 float視為double (即單精度)。

這些不起作用。

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

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

這將不可分割的轉換double為精確uint32_t (只要沒有溢出,達到2 ^ 32-1)。 如果雙精度數是Nan或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;
 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM