将对齐的数组uint8 [8]转换为double

时间:2012-05-02 13:46:54

标签: ios c double bit-manipulation core-foundation

我在尝试将对齐的数组uint8[8]转换为double时遇到了一些挑战。 使用位操作将uint8[4]转换为long特别容易,但我知道double在符号位方面会变得混乱吗?

在Java中,我只使用ByteBuffer.wrap(bytes).getDouble(),但我认为它在C中并不那么容易。

我尝试实现此代码,但最后一个命令提供错误Expression is not assignableShift count >= width of type

long tempHigh = 0; 
long tempLow = 0;
double sum = 0;
tempHigh |= buffer[0] & 0xFF;
tempHigh <<= 8;
tempHigh |= buffer[1] & 0xFF;
tempHigh <<= 8;
tempHigh |= buffer[2] & 0xFF;
tempHigh <<= 8;
tempHigh |= buffer[3] & 0xFF;

tempLow |= buffer[4] & 0xFF;
tempLow <<= 8;
tempLow |= buffer[5] & 0xFF;
tempLow <<= 8;
tempLow |= buffer[6] & 0xFF;
tempLow <<= 8;
tempLow |= buffer[7] & 0xFF;

sum |= ((tempHigh & 0xFFFF) <<= 32) + (tempLow & 0xFFFF);

如何正确完成此程序只是解决我所犯的错误?

提前致谢。

3 个答案:

答案 0 :(得分:3)

double是浮点类型;它不支持按位操作,例如|

您可以执行以下操作:

double sum;

memcpy(&sum, buffer, sizeof(sum));

但要注意字节序问题。

答案 1 :(得分:2)

工会怎么样?写你的长部分,然后双重自动正确。像这样:

union 
{
   double sum;
   struct
   {
       long tempHigh;
       long tempLow;
   }v;
 }u;

 u.v.tempHigh = 0; 
 u.v.tempHigh |= buffer[0] & 0xFF;
 u.v.tempHigh <<= 8;
 u.v.tempHigh |= buffer[1] & 0xFF;
 u.v.tempHigh <<= 8;
 u.v.tempHigh |= buffer[2] & 0xFF;
 u.v.tempHigh <<= 8;
 u.v.tempHigh |= buffer[3] & 0xFF;

 u.v.tempLow |= buffer[4] & 0xFF;
 u.v.tempLow <<= 8;
 u.v.tempLow |= buffer[5] & 0xFF;
 u.v.tempLow <<= 8;
 u.v.tempLow |= buffer[6] & 0xFF;
 u.v.tempLow <<= 8;
 u.v.tempLow |= buffer[7] & 0xFF;

 printf("%f", u.sum);

答案 2 :(得分:2)

可行的方法是使用逐位算术将符号,指数和尾数值读出为整数变量,然后调用ldexp来应用指数。

好的,这是一些代码。请注意,它可能有不匹配的括号或逐个错误。

unsigned char x[8]; // your input; code assumes little endian
long mantissa = ((((((x[6]%16)*256 + x[5])*256 + x[4])*256 + x[3])*256 + x[2])*256 + x[1])*256 + x[0];
int exp = x[7]%128*16 + x[6]/16 - 1023;
int sign = 1-x[7]/128*2;
double y = sign*ldexp(0x1p53 + mantissa, exp-53);