我在尝试将对齐的数组uint8[8]
转换为double
时遇到了一些挑战。
使用位操作将uint8[4]
转换为long
特别容易,但我知道double
在符号位方面会变得混乱吗?
在Java中,我只使用ByteBuffer.wrap(bytes).getDouble()
,但我认为它在C中并不那么容易。
我尝试实现此代码,但最后一个命令提供错误Expression is not assignable
和Shift 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);
如何正确完成此程序或只是解决我所犯的错误?
提前致谢。
答案 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);