简体   繁体   English

在不支持双精度的C编译器上将64位双精度浮点数据转换为Uint32

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

I need to decode a timestamp encoded as an IEEE double (from iOS NSTimeInterval ) and stored in a 8 byte array, so that I can use ctime to print out the timestamp in a human readable format. 我需要解码一个编码为IEEE double的时间戳(从iOS NSTimeInterval )并存储在8字节数组中,以便可以使用ctime以人类可读的格式打印该时间戳。 This is trivial on most systems, but not on mine. 这在大多数系统上都是微不足道的,但在我的系统上却并非如此。

Example: on iOS side

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

I'm running on a MSP430F5438A and I need to use the COFF ABI to link with 3rd part libraries. 我在MSP430F5438A上运行,我需要使用COFF ABI与第三部分库链接。 TI's Code Composer does not support 64-bit floating point types (IEEE double) if you use the COFF ABI. 如果使用COFF ABI,则TI的Code Composer不支持64位浮点类型 (IEEE double)。 It treats double the same as float (ie single precision). float视为double (即单精度)。

These don't work. 这些不起作用。

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

or 要么

x = *(double*)data;

or 要么

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

I just get gibberish, because double is only 4 bytes using Code Composer. 我只是有点乱码,因为使用Code Composer, double仅为4个字节。 I need a way to directly convert the uint8_t[8] data (which is a legitimate IEEE double precision value) into an integer value. 我需要一种直接将uint8_t[8]数据(这是合法的IEEE双精度值)转换为整数值的方法。

This will convert an integral double to an exact uint32_t (as long as there is no overflow, up to 2^32-1). 这将不可分割的转换double为精确uint32_t (只要没有溢出,达到2 ^ 32-1)。 It will not work if the double is Nan or Inf, but that is unlikely. 如果双精度数是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