私はコンピュータサイエンス大学でいくつかの演習を行っていますが、そのうちの1つはint
、64ビットの配列を倍精度浮動小数点値に変換することです。
最初のビットである符号+/-を理解するのは非常に簡単です。指数についても同じであり、バイアスが1023であることもわかっています。
仮数に問題があります。どうすれば計算できますか?
最後に、ビットが意味する実数を取得したいと思います。
私はコンピュータサイエンス大学でいくつかの演習を行っていますが、そのうちの1つはint
、64ビットの配列を倍精度浮動小数点値に変換することです。
最初のビットである符号+/-を理解するのは非常に簡単です。指数についても同じであり、バイアスが1023であることもわかっています。
仮数に問題があります。どうすれば計算できますか?
最後に、ビットが意味する実数を取得したいと思います。
ビットを double と同じサイズの符号なし整数にロードし、そのアドレスを取得してにキャストし、それを avoid*
にキャストしてdouble*
逆参照するだけです。
もちろん、浮動小数点標準を本当に解析することになっている場合、これは「不正行為」である可能性がありますが、これまでに述べたパラメーターを考えると、これが問題を解決する方法です。
与えられた 64 ビットの仮数を計算するのはとても簡単です。
IEEE 754 を使用するwiki の記事によると、有意桁は最初の 53 ビット (ビット 0 からビット 52 まで) で構成されます。67 ビットのような数値を 64 ビットの値に変換する場合は、値の末尾の 64 番目のビットを 1 に設定することで丸められます。以前は 1 だったとしても...他の 3 ビットのために:
11110000 11110010 11111は、最後のバイトの丸め後に11110000 11110011になります。
したがって、53 番目のビットは常に値が 1 であるため、格納する必要はありません。そのため、仮数部に 53 ではなく 52 ビットのみを格納します。
これを計算するには、仮数のビット範囲 [bit(1) - bit(52)] -bit(0) is always 1- をターゲットにして、それを使用するだけです。
int index_signf = 1; // starting at 1, not 0
int significand_length = 52;
int byteArray[53]; // array containing the bits of the significand
double significand_endValue = 0;
for( ; index_signf <= significand_length ; index_signf ++)
{
significand_endValue += byteArray[index_signf] * (pow(2,-(index_signf)));
}
significand_endValue += 1;
byteArray
次のような関数を使用して、計算する前に適切に入力する必要があります。
int* getSignificandBits(int* array64bits){
//returned array
int significandBitsArray[53];
// indexes++
int i_array64bits = 0;
int i_significandBitsArray=1;
//set the first bit = 1
significandBitsArray[0] = 1;
// fill it
for(i_significandBitsArray=1, i_array64bits = (63 - 1); i_array64bits >= (64 - 52); i_array64bits--, i_significandBitsArray ++)
significandBitsArray[i_significandBitsArray] = array64bits[i_array64bits];
return significandBitsArray;
}
オブジェクトのバイト表現がある場合は、バイトを正しい型の変数のストレージにコピーして変換できます。
double convert_to_double(uint64_t x) {
double result;
mempcy(&result, &x, sizeof(x));
return result;
}
変換を行うようなコードをよく見かけます*(double *)&x
が、実際にはこれは常に機能しますが、C では未定義の動作です。