7

リトル エンディアン用の Visual Studio TC コンパイラを使用しています。以下はコードの一部です。

void main()
{    
    float c = 1.0;
    int a = 0x3F800000;
    int *ptr = (int *)&c;
    printf("\n0x%X\n", *ptr);
    printf("\na = %f", a);
    printf("\nc = %f", c);
    return;    
}

出力は次のとおりです。

0x3F800000
a = 0.000000
c = 1.000000

浮動小数点値 1.0 は 0x3F800000 であり、リトル エンディアンのメモリに 00 00 80 3F として格納されます。int a にも同じ値が代入されます。printf はどのように int a に対して 0.000000 を出力し、float c に対して 1.000000 を出力しますか? printf で %f を使用して印刷すると、すべての整数値が 0.000000 として印刷されるのを見てきました。

また、printf は可変引数関数なので、レジスタに渡された値が int か float かをどのように判断するのでしょうか?

4

7 に答える 7

5
于 2013-05-17T11:42:33.267 に答える
5

コードを gcc でコンパイルしました。生成されたコードは次のとおりです。

movl    $0x3f800000, %eax
movl    %eax, -4(%ebp)
movl    $1065353216, -8(%ebp)
leal    -4(%ebp), %eax
movl    %eax, -12(%ebp)
movl    -12(%ebp), %eax
movl    (%eax), %eax
movl    %eax, 4(%esp)
movl    $LC1, (%esp)
call    _printf
movl    -8(%ebp), %eax
movl    %eax, 4(%esp)
movl    $LC2, (%esp)
call    _printf
flds    -4(%ebp)
fstpl   4(%esp)
movl    $LC3, (%esp)
call    _printf

これは、浮動小数点パラメーターが通常のスタックからではなく、浮動小数点のスタックから取得されるというヒントを与える可能性があります...0ではなくランダムなものがあると思います...

于 2013-05-17T11:27:19.530 に答える
1

私は同様の問題に遭遇し、最終的にそれを解決する方法を開発しましたが、それがあなたが望むものかどうかはわかりません。

#include <stdio.h>
void printIntAsFloat();

int main(void){
    printIntAsFloat();
}

void printIntAsFloat(){
    float c = 1.0;
    int a = 0x3F800000;
    int *ptr = (int *)&c;
    float *fp = (float*)((void*)&a); /*this is the key point*/
    printf("\n0x%X\n", *ptr);
    printf("\na = %f", a);
    printf("\nc = %f", c);
    printf("\nfp = %f", *fp);
    return; 
} 

出力は次のようになります。

0x3F800000

a = 0.000000
c = 1.000000
fp = 1.000000

OS : Fedora21 64 ビット GCC バージョン : gcc バージョン 4.9.2 20141101 (Red Hat 4.9.2-1) (GCC)

于 2015-04-07T01:23:14.103 に答える
-1
int a= 0x3F800000;
printf("\na = %f", *(float*)&a);//1.0
于 2013-05-17T11:43:02.883 に答える
-1

変数をキャストする

printf("\na = %f", (float)a);
printf("\nc = %f", (float)c);
于 2013-05-17T11:26:57.197 に答える