ここで浮動小数点数の絶対値を見つけるためのアルゴリズム。これはどのように作動しますか?
//find absolute value
double x;
*(((int *) &x) + 1) &= 0x7fffffff;
1 のオフセットが必要だった理由がわかりません。それは言います:
IA32 64 ビット符号ビットは、+1 の int アドレス オフセットで 0x80000000 です。
誰かがこれを分解して説明できますか?
ここで浮動小数点数の絶対値を見つけるためのアルゴリズム。これはどのように作動しますか?
//find absolute value
double x;
*(((int *) &x) + 1) &= 0x7fffffff;
1 のオフセットが必要だった理由がわかりません。それは言います:
IA32 64 ビット符号ビットは、+1 の int アドレス オフセットで 0x80000000 です。
誰かがこれを分解して説明できますか?
このコードは厳密なエイリアシング規則に違反しているため、技術的に無効な C です。ただし、エイリアス規則を乱用しないようにコンパイラに指示すると、x86 と同じようにdouble
s とs がメモリ内に配置されることが保証されます。int
(int *)&x
へのポインタx
です。1 を追加すると、ポインタが 4 バイト前方に移動します。それを逆参照すると、 の 4 ~ 7 バイト目が得られますdouble
。の最後のバイトであるため、これの上位ビットをマスクしますdouble
。
char *
ちなみに、a を使用して1 の代わりに 7 を追加することで、これがエイリアシング違反になるのを防ぐことができます。
Adouble
は 8 バイト幅で、次の形式です。
int
表示するコードは、幅が 4 バイトであり、 と の両方int
がdouble
リトルエンディアンであることを前提としています(つまり、ビット 0 ~ 7 はバイト 0 に格納され、ビット 8 ~ 15 はバイト 1 などに格納されます)。
x
へのポインターの場合double
:
*(((int *) &x) + 0) addresses bits 0 through 31;
*(((int *) &x) + 1) addresses bits 32 through 63.
したがって、*(((int *) &x) + 1) &= 0x7fffffff
ビット 63 をゼロに設定x
し、その絶対値に変更します。
これはプラットフォームに大きく依存します。
とにかく、最上位ビットが符号ビットである double があります。
double が 8 バイトで int が 4 バイトで、LE システムを使用している場合、最上位ビットは最後のバイトまたは 2 番目の整数の最上位ビットです。
したがって、2 番目の整数 ( と書くこともできます((int *)&x)[1] &= 0x7fffffff
) を取り、その最上位ビットをクリアします。