私は、2つの32ビットのunsinged int:unsigned int[2]
として書かれた64ビットの数値を持っています。 unsigned int[0]
はMSB、unsigned int[1]
はLSBです。どのように私はそれをdouble
に変換するでしょうか?ダブルからunsigned int [2]?
double d_from_u2(unsigned int*);
私は、2つの32ビットのunsinged int:unsigned int[2]
として書かれた64ビットの数値を持っています。 unsigned int[0]
はMSB、unsigned int[1]
はLSBです。どのように私はそれをdouble
に変換するでしょうか?ダブルからunsigned int [2]?
double d_from_u2(unsigned int*);
2つの整数のビットをdouble
のオブジェクトにコピーする方法はいくつかあります。最低レベルでは
、あなたは、戻り値の最初のバイトに[unsigned
] char *
を作成し、あなたが選択したあらゆる手段によって、それらの間でコピーし、[unsigned
] char *
にご入力ポインタを変換することができます。これにより、必要に応じてバイトオーダーを調整する機会がすべて提供されます。たとえば、配列が最も重要な順序で配列されていますが、ワードが最初に必要です。
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;
}
:あなたはバイトが最初にあなたのdouble
最上位バイトに転送されるように、そしてあなたは、マシンバイト順序に依存しないことを、あなたがこれを行う可能性があります必要がある場合は
算術演算(この場合はシフト)を使用すると、数値表現の詳細とは独立して入力の数値を操作することができます。ここで
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 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];
を希望する任意の順序でバイトごとに
unsigned char
の配列として送信元と宛先の両方のオブジェクトを再解釈し、それらをコピーすることができます
(2番目の例は、最初の例と同じではありません)
'memcpy'は使用できません。申し訳ありません。 – Danijel
@ダニエル:まず、質問には奇妙な制限が言及されるべきです...あなたが「使用できない」ことが他にありますか?第二に、 'memcpy'を使うことができない場合は、明示的に手動で明示的に記述することができます。 'n'バイトをコピーするだけの単純なサイクルです。サイクルなしで、バイト単位のコピーとして表現することもできます。 – AnT
答えの正しさは本当に重要ではありませんが、私は 'assert'を' static_assert'(C11とすべての良いものを前提としています)にします。 – StoryTeller
はunion
を使用してmemcpy
せずに動作しますが、解決策です:
#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を参照してください。 Inは、ユニオン内の配列int32_t[2]
を初期化し、int64_t
を使用してdouble
に変換します。初期化の順序は、実行するマシン(リトルエンディアンまたはビッグエンディアン)、または値がどこから来るかによって異なります(1最初)。
2つの 'unsigned int 'のビットを' double'に転送する方法を尋ねていますか、または「written as」は必要な変換に何か意味がありますか? –
ジョン、ちょうど転送します。 – Danijel
'typedef union {unsigned int iVar [2];ダブルdVar; } i2d; '? – KevinDTimm