[英]C - fail to convert unsigned char array to double
我想在C中將無符號char數組轉換為double。我嘗試了很多方法,但是仍然錯誤地轉換為0.00000。
union {
double longtitude;
unsigned char bytes[sizeof(double)];
}u;
unsigned char * receive_buffer = malloc(65536);
int recv = recv(fd,receive_buffer,65536,0);
// the buffer should has 8 byte value {40 5c 80 23 8d a3 c2 12}
memcpy(&u.bytes,receive_buffer,sizeof(double)); // copy to char array
for ( int i=8;i>=0;i--){
u.longtitude = u.bytes[i];
}
printf("%lf",u.longtitude); // the result is 0.000000 / the expected result should be 114.00217
我從互聯網上找到的上述代碼得到了“ 0.000000”的結果。 如何將char數組轉換為double? 上面的代碼有什么問題?
UPDATE
我在上面添加了更具體的代碼。 我已經檢查了receive_buffer
的內容,它包含上述注釋中的值。 u.bytes
可以通過memcpy
從緩沖區正確獲取一個值。 union and for loop
部分是我從其他類似問題中發現的方式。 我嘗試過,但結果= 0.000000。 抱歉,以前發布的代碼不明確,之前提到的問題; 我是C語言的新手。
刪除for
循環。
memcpy
將緩沖區中的bytes
復制到聯合的bytes
數組中。 這些字節與longitude
成員使用的字節相同,因此它們已經就位。 您不需要for
循環來復制這些字節,並且它錯誤地將字節的值寫入double的值 ,而不是寫入表示該值的字節。 同樣,循環索引是錯誤的,因為它在第一次迭代中使用8,但是將8字節對象中的字節索引為0到7。
不僅如此,在C語言中,您可以使用union或memcpy
修改表示對象的字節。 您不需要兩者。 在recv
,滿足:
double longitude;
memcpy(&longitude, receive_buffer, sizeof longitude);
我希望,你甚至可以做recv
直接進入&longitude
。
完全刪除for
循環。 我不確定您打算在那里使用它的意圖是什么,但是它會使您剛剛做的工作無法(或者更像是bb語)。
根據您的更新和114.00217
,問題是字節順序。 無論您要從中獲得價值的任何機器,都沒有與您的機器相同的耐久性。 因此,在轉換為兩倍后,交換極性。
// endian_swap() function taken from https://stackoverflow.com/a/21507710/669576
// I modified to work with double
double endian_swap(double d)
{
long x = *(long *)&d;
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
return *(double *)&x;
}
int main(void) {
unsigned char s[] = {0x40,0x5c,0x80,0x23,0x8d,0xa3,0xc2,0x12};
double d;
// Just copy - no union needed
memcpy(&d, s, sizeof(d));
// Swap endianess
d = endian_swap(d);
printf("%lf\n", d);
return 0;
}
輸出:114.002170
我沒有做很多網絡編程,但是我相信ntohl()
函數用於此目的。 但是,我不知道是否有64位版本。
更新:另外,您可以使用htobe64()
(感謝@Stargateur):
#include <endian.h>
int main(void) {
unsigned char s[] = {0x40,0x5c,0x80,0x23,0x8d,0xa3,0xc2,0x12};
// htobe64() expects a long, so use that first
long l;
memcpy(&l, s, sizeof(l));
l = htobe64(l);
// Then copy the swapped long bits to a double
double d;
memcpy(&d, &l, sizeof(d));
printf("%lf\n", d);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.