我有一個64位數字寫成兩個32位不帶符號整數:unsigned int[2]
。 unsigned int[0]
是MSB,而unsigned int[1]
是LSB。我如何將它轉換爲double
?無符號整型[2]?
double d_from_u2(unsigned int*);
我有一個64位數字寫成兩個32位不帶符號整數:unsigned int[2]
。 unsigned int[0]
是MSB,而unsigned int[1]
是LSB。我如何將它轉換爲double
?無符號整型[2]?
double d_from_u2(unsigned int*);
有幾種方式可將兩個整數的比特複製到double
類型的對象。
在最低級別,您可以將輸入指針轉換爲[unsigned
] char *
,創建一個[unsigned
] char *
的返回值的第一個字節,而那些不擇手段您選擇之間複製。這爲您提供了根據需要調整字節順序的一切機會 - 例如,儘管您的數組首先排序的是最重要的字,但這些字中的字節順序可能不是您需要的。
在您需要的字節數的情況下被轉移到你的double
最顯著字節在前,而且你不想依賴於機器的字節順序,你可以這樣做:
double d_from_u2(unsigned int *in) {
double result;
unsigned char *result_bytes = (unsigned char *) &result;
for (int i = 0; i < 4; i++) {
result_bytes[i] = in[0] >> (24 - 8 * i);
result_bytes[i + 4] = in[1] >> (24 - 8 * i);
}
return result;
}
使用算術(在這種情況下,移位)允許您對輸入的數值進行操作,而與數字表示的細節無關。
memcpy
它從源陣列,以在適當的順序一個double
對象。例如。如果你希望交換的unsigned
部分課程
unsigned src[2] = { ... };
double dst;
assert(sizeof dst == sizeof src);
memcpy(&dst, &src[1], sizeof(unsigned));
memcpy((unsigned char *) &dst + sizeof(unsigned), &src[0], sizeof(unsigned));
,你永遠可以重新解釋的源和目標對象爲unsigned char
陣列和複製它們逐字節任何順序,你希望
unsigned src[2] = { ... };
double dst;
unsigned char *src_bytes = (unsigned char *) src;
unsigned char *dst_bytes = (unsigned char *) &dst;
assert(sizeof dst == 8 && sizeof src == 8);
dst_bytes[0] = src_bytes[7];
dst_bytes[1] = src_bytes[6];
...
dst_bytes[7] = src_bytes[0];
(第二個例子並不意在等同於第一個。)
不能使用'memcpy',抱歉。 – Danijel
@Danijel:首先,怪問題通常應該在問題中提及......還有什麼「你不能使用」的東西?其次,如果你不能使用'memcpy',你可以明確地手動拼出它。這只是一個複製'n'字節的簡單循環。您甚至可以將其無循環地表示爲逐字節複製。 – AnT
對於答案的正確性並不重要,但我會將'assert'變成'static_assert'(假設C11和所有這些好東西)。 – StoryTeller
這裏是一個解決方案,而無需memcpy
工作,但使用union
:
#include "stdio.h"
#include "stdint.h"
double d_from_u2(unsigned int* v) {
union {
int32_t x[2];
int64_t y;
} u = { .x = { v[1], v[0] }};
printf("%llu\n", u.y); // 1311768467463794450
return (double)u.y;
}
int main(void) {
int32_t x[2];
x[0] = 0x12345678;
x[1] = 0x9abcef12;
printf("%f\n", d_from_u2(x)); // 1311768467463794432.000000
return 0;
}
見demo。在初始化聯合中的數組int32_t[2]
並使用int64_t
將其轉換爲double
。初始化的順序取決於它運行的是哪臺機器(小端或大端)或值來自何處(首先是1)。
你問你如何將你的兩個'unsigned int'的位轉換爲'double',或者「寫爲」對於所需的轉換還有其他含義嗎? –
約翰,只是轉移。 – Danijel
'typedef union {unsigned int iVar [2];雙倍變化; } i2d;'? – KevinDTimm