デスクトップにVS2013 Expressを使用して、Windows 7 64ビットを使用しています。
デフォルトとしてコンパイル (SSE を使用)
D:\Work>cl printf-test.c
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
D:\Work>printf-test.exe
FPU control word 0x0000037f
0. FPU status 0x00000000
1. 0x43380000 0x00000000
1. FPU status 0x00000000
2. 0x43380000 0x00000001
2. FPU status 0x00000000
3. 0x43380000 0x00000001 //@@1
3. FPU status 0x00000000
x87 のみを使用してコンパイルします。
D:\Work>cl /arch:IA32 printf-test.c
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
D:\Work>printf-test.exe
FPU control word 0x0000037f
0. FPU status 0x00000000
1. 0x43380000 0x00000000
1. FPU status 0x00000020
2. 0x43380000 0x00000001
2. FPU status 0x00000220
3. 0x43380000 0x00000000 //@@1 this is the difference. why?
3. FPU status 0x00000020
以下のようなテストコード
#include <stdio.h>
void print_double_hex( double d , int idx)
{
union UD
{
double d;
int i[2];
} c;
c.d = d + 6755399441055744.0;
printf("%d. 0x%08x 0x%08x\n", idx, c.i[1], c.i[0]);
}
void PrintControlWord()
{
int a;
int c;
__asm {
fstcw [esp - 4]
mov eax, [esp - 4]
and eax, 0xFFFF
mov c, eax
}
printf("FPU control word 0x%08x\n", c);
}
void PrintStatus(int idx)
{
int a;
int c;
__asm {
fstsw [esp - 4]
mov eax, [esp - 4]
and eax, 0xFFFF
mov c, eax
}
printf("%d. FPU status 0x%08x\n", idx, c);
}
int main()
{
double a = .5;
double b = 0.501;
double c = 0.5001;
int fpu = 0;
__asm { // @@2 Remove it, see result below
finit
}
PrintControlWord();
PrintStatus(0);
print_double_hex(a, 1);
PrintStatus(1);
print_double_hex(b, 2);
PrintStatus(2);
print_double_hex(c, 3);
PrintStatus(3);
return 0;
}
FPU を削除する場合は、手動で初期化することに注意してください。結果が変わる!
を削除した後finit
、デフォルトでコンパイル
D:\Work>cl printf-test.c
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
D:\Work>printf-test.exe
FPU control word 0x0000027f //@@2 FPU control word changed, why?
0. FPU status 0x00000000
1. 0x43380000 0x00000000
1. FPU status 0x00000000
2. 0x43380000 0x00000001
2. FPU status 0x00000000
3. 0x43380000 0x00000001
3. FPU status 0x00000000
x87 のみを使用してコンパイルする
D:\Work>cl /arch:IA32 printf-test.c
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
D:\Work>printf-test.exe
FPU control word 0x0000027f
0. FPU status 0x00000000
1. 0x43380000 0x00000000
1. FPU status 0x00000020
2. 0x43380000 0x00000001
2. FPU status 0x00000020
3. 0x43380000 0x00000001 //@@3, why?
3. FPU status 0x00000020
だから私の質問は:
について
@@1
、なぜ違うのですか?バグですか?について
@@3
、値が変更された理由は?