2016-03-29 12 views
0

変数をfloatとして宣言して2つの16進数を減算すると、コンパイルして実行するたびに異なる回答が得られます。コードをコンパイルして実行するたびに、結果が同じままになります。フロートに結果を格納すると、同じ2つの数字(は0xFF0000 - 0xFF7FF)の違いで、私はコンパイル毎回変わる理由を私は理解していない16進数を減算する

int main() 
{ 
    float BlocksLeft = 0xFF0000 - 0xFF7FF; 
    int BLeft = 0xFF0000 - 0xFF7FF; 

    printf("%08x\n", BlocksLeft); 
    printf("%08x\n", BLeft); 
} 
+0

を、私はこのオンラインコンパイラを使用しています http://www.tutorialspoint.com/compile_c_online.php –

+4

フロートは、符号なし整数ではありませんしたがって、 '%x'はUBにつながる 'BlocksLeft'のフォーマット指定子として不正です。 –

+0

'float'を出力して意味を調べるには' printf( "%。9e \ n"、BlocksLeft); '%08x'は符号なし整数です。 – chux

答えて

4

次の行が正しくありません:

printf("%08x\n", BlocksLeft); 

%xフォーマットあなたが与える引数がintであることをコンパイラに示します。これは未定義の動作につながります。私はあなたのコードをコンパイルしようとした私が得た:

>gcc -Wall -Wextra -Werror -std=gnu99 -o stackoverflow.exe stackoverflow.c 
stackoverflow.c: In function 'main': 
stackoverflow.c:15:4: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'double' [-Werror=format=] 
    printf("%08x\n", BlocksLeft); 
    ^

、少なくとも-Wall強い警告レベルでコンパイルしてみてください。

あなたはあなたのプログラムは、例えば、この方法を修正することができます。

#include <stdio.h> 

int main() 
{ 
    float BlocksLeft = 0xFF0000 - 0xFF7FF; 
    int BLeft = 0xFF0000 - 0xFF7FF; 

    printf("%08x\n", (int) BlocksLeft); // Works because BlocksLeft's value is non negative 
    // or 
    printf("%08x\n", (unsigned int) BlocksLeft); 
    // or 
    printf("%.8e\n", BlocksLeft); 

    printf("%08x\n", BLeft); 
} 
+0

詳細: '"%x "'は 'unsigned'です。 '"%x "'はまた、非負の 'int'で動作します。 – chux

+0

@chux詳細が大好き!回答が編集されました。 – jdarthenay

+0

詳細: ''%x "'は 'unsigned':" ...、x、X '' unsigned int'引数は変換されます... "C11§7.21.6.18' fprintf'関数。 ''%x "'は、宣言された1つの型が符号付き整数型であり、もう1つの宣言型が対応する符号なし整数型であり、その値が両方の型で表現可能であるため、負でない 'int ' §6.5.2.26関数呼び出し '...' – chux