2017-01-24 30 views
0

は、だから私は、次のような出力を解釈しようとしている:短いintとunsigned shortの出力?

short int v = -12345; 
unsigned short uv = (unsigned short) v; 

printf("v = %d, uv = %u\n", v, uv); 

Output: 
v = -12345 
uv = 53191 

そうです質問:このプログラムは、2の補数のマシン上で実行されたときに、なぜこの正確な出力が生成されますか?

unsigned shortに値をキャストすると、この結果につながる操作はありますか?

+1

私に見えます。あなたはどんな結果を期待しましたか? –

+0

@SteveSummit実際には私には間違っているようです... http://port70.net/~nsz/c/c11/n1570.html#6.3.1.3p2によると、それは '53190'であるはずです。私が正しくそれを読んでいるなら... –

+0

@EugeneSh。あなたは正しくそれを読んでいません;-) –

答えて

2

私の答えは、16-bitの2の補数演算を前提としています。

-12345の値を見つけるには、12345とし、それを補完し、1を追加します。 S 'の1にS' sのすべての1 'が0にS' の、すべての0を変更

12345 is 0x3039 is 0011000000111001. 

補完手段:

1100111111000110 is 0xcfc6 is 53190. 

は1を追加します53191

内部的には、-123450xcfc7 = 53191で表されます。

しかし、それを符号なしの数字と解釈すると、それは明らかにちょうど53191です。 (符号付きの値を同じサイズの符号なし整数に代入すると、何も変換されずに正確なビットパターンが割り当てられますが、通常、あなたは%uでそれを印刷してください。)

これについて考える別の、おそらくもっと簡単な方法を16-bit算術だから、あなただけ(0の別の名前であるとして65536と考えることができます2 = 65536で「ラップアラウンド」ということです0:0024:00はどちらも真夜中の名前です)。従って-1234565536 - 12345 = 53191です。

+0

ありがとうございました...私はちょうどそれをやっていましたが、どういうわけか私は迷ってしまいました。最後の文は実際にそれを見て良い方法です。 :)ありがとうございました –

+0

答えの最初の部分は、C言語の文脈での質問とは関係ありません。この動作は、マシンの「2相補性」に依存しません。変換と再解釈は全く異なる2つの概念です。この場合、コンバージョンを扱っています。再解釈はまったく必要ありません。それを再解釈して説明しようとすると、言い表すのは間違いです。 – AnT

+0

@AnT私の答えは、C言語にはまったく対処するつもりはありませんでした.2つの補数演算を説明しました。これは、OPが尋ねたものです。 「解釈」についての括弧は意図的に曖昧でしたが、私は少し言い換えました。 –

1

変換規則は、符号付き整数を符号なし整数に変換するときに、C規格で定義されている場合には、値にTYPE_MAX + 1を繰り返し追加する必要があります。 6.3.1.3 Signed and unsigned integersから

新しいタイプが符号なしの場合にそうでない場合、値が繰り返し 値まで、新しいタイプで表現することができる最大値より1を加算または減算 によって変換され新しいタイプの の範囲にあります。

USHRT_MAXは65535、その後65535 + 1 + -1234553191で追加された場合。

1

出力は2の補数にも16または32ビットのintにも依存しません。見られる出力は完全に定義されており、まれな1の補数または符号量マシンでは同じになります。結果は16ビットに依存しますunsigned short

-12345は、その割り当てに問題がないように、shortの最小範囲内にあります。 ... shortが...引数として渡された場合、shortintの範囲にあるため、通常のプロモーションはintに変更されず、値の変更はありません。 "%d"intを期待するので、出力は

short int v = -12345; 
printf("%d\n", v); // output "-12345\n" 

"-12345"が明確に定義された符号なしの型に負の数を割り当てています。 16ビットunsigned shortと、uvの値が、値は...引数としてunsigned shortを渡す53191.

の最終値に(この例では65536)USHRT_MAX+1の最小倍数プラス-12345でありますintまたはunsignedに変換されます。いずれのタイプにも、unsigned shortの全範囲が含まれます。 IAC、は変更されません。 "%u"unsignedと一致します。値がintまたはunsignedのいずれかとして表示されるintにも一致します。符号なしshortに値をキャストしたときに、この結果につながるどのような操作

short int v = -12345; 
unsigned short uv = (unsigned short) v; 
printf("%u\n", v); // output "53191\n" 

キャスティングは最終結果に影響しませんでした。同じ結果がキャストなしで起こったでしょう。キャストは静かな警告に役立つかもしれません。

+0

私は今、あなたのお手伝いをしてくれてありがとうございました。それは私がこれを理解するのを本当に助けました。 –

関連する問題