質問
ることもあって、以下のCコードです。
unsigned int u = 1234;
int i = -5678;
unsigned int result = u + i;
何を暗黙的に変換を継続して行っており、今後はここに、このコードは安全のためのすべての値の u
や i
?(安全なようになったという意味のもの 結果 この例では、オーバーフローの一大正数、キャストです int や実際の結果です。)
解決
短答
ご i
ます 変換され を符号なし整数の追加 UINT_MAX + 1
, そのほかにわたって実施されること符号なしの値が、 result
によっての価値 u
や i
).
長い回答
によると、C99の標準:
6.3.1.8通常の算術の変換
- 場合は両方のオペランドが同一の型を押し付けるのではなく、その一層の変換が必要です。
- そうではない場合、両方のオペランドが署名してい整数タイプと符号なし整数タイプには、オペランドのタイプの少ない整数に変換ランクに変換されるタイプのオペランドよります。
- その場合、オペランドが符号なし整数型のランク以上のランクの種類、その他の演算子のオペランドと符号付き整数型に変換されるタイプのオペランドとの符号なし整数タイプです。
- その場合には、オペランドと符号付き整数型を表現できる値はすべてのタイプのオペランドとの符号なし整数タイプのオペランドとの符号なし整数型に変換されるタイプのオペランドと符号付き整数型です。
- その他、両方のオペランドに変換符号なし整数型に対応するタイプのオペランドと符号付き整数型です。
このケースではあたしアニメ見てましたunsigned int(u
や署名のint(i
).参照(3)上記以降の両方のオペランドは同じランク、 i
する必要がある 変換され を符号なし整数です。
6.3.1.3署名の符号なし整数
- 値が整数型に変換される別の整数タイプ以外の_Bool場合の値で表すことができる、新しいタイプでは変わらず。
- その場合、新しいタイプは、符号なしの値に変換される繰り返し追加を差し引いた一つ以上の最大値を表すことができる新しいタイプまでの価値の範囲は、新しいタイプです。
- そうでない場合は、新しいタイプに署名した値を表示できないですどちらの結果は実装で定義されていますまたは実装で定義されています信号を上げています。
今後は(2)参照。ご i
に変換される符号なし値の追加 UINT_MAX + 1
.その結果によってどのよう UINT_MAX
定義されているので自の実装です。でかかりますが、これませんがオーバフローするためには、多くの
6.2.5 (9)
の計算に関符号なしオペランドがオーバーフローなので、結果的に表現するには、符号なし整数タイプの低減モデューロ製することで、一つ以上の最大値で表すことができるのよ。
ボーナス:算数変換セミ稿
#include <stdio.h>
int main(void)
{
unsigned int plus_one = 1;
int minus_one = -1;
if(plus_one < minus_one)
printf("1 < -1");
else
printf("boring");
return 0;
}
利用できるこのリンクを試してオンライン: https://repl.it/repls/QuickWhimsicalBytes
ボーナス:算数変換側の効果
算数の変換ルールを使うことができますの値 UINT_MAX
による初期化する符号なし値 -1
, ie:
unsigned int umax = -1; // umax set to UINT_MAX
この保証するものではあ携帯にかかわらず符号付きの数の表現システムのための変換規則を記述す。これで問題となりました。 で安全に使用-1に設定すべてのビット。
他のヒント
変換には符号なし ない ずコピーまたは解釈の表現に署名した。引用のCを標準(C99 6.3.1.3):
値が整数型に変換される別の整数タイプ以外の_Bool場合 の値で表すことができる、新しいタイプでは変わらず。
その場合、新しいタイプは、符号なしの値に変換される繰り返し追加 を差し引いた一つ以上の最大値を表すことができる新しいタイプ までの価値の範囲は、新しいタイプです。
そうでない場合は、新しいタイプに署名した値を表示できないですのいずれか 結果は実装で定義されていますまたは実装で定義されています信号を上げています。
のの補数表現がほぼ普遍的なこれらの日はルールな対応を釈します。ものその他の表示(看板、絶対値または己補体のC実装なければならな手配を同じ結果には変換できなだけをコピーします。例えば、(unsigned)-1==UINT_MAXにかかわらず、表現。
一般変換は、Cで定義される操作上の値ではなく、表現に変換するものである。
回答の質問:
unsigned int u = 1234;
int i = -5678;
unsigned int result = u + i;
の価値を私に変換されunsigned int,降伏 UINT_MAX + 1 - 5678
.この値は、次の符号なし値1234雑な UINT_MAX + 1 - 4444
.
(符号なしとは異なりオーバーフローに署名されたオーバーフローを呼び出しません.ラップアラウンドが共通のものではありませんCの基準、コンパイラの最適化を可能に打撃を与えコードが主張には根拠がな前提をアップデート。)
参照 聖書の中:
- します動作の原因をintに変換できる符号なしint.
- と仮定して二つの補数表現と同等サイズのタイプには、ビットパターンは変わりません。
- 変換符号なしint値の署名intは、実装に依存します。がそれぞれの作品に期待するほとんどのプラットフォームです。)
- ルールはちょっと複雑に組み合わせ署名を付けるの異なるサイズです。
が符号なしと署名した変数を追加(またはずのバイナリの動作にも暗黙的に変換される符号なし、この場合、結果に大きます。
なので安心感との結果が大きく、間違ったものの、こンダリングする能力があります。
がに変換する署名を符号なしが可能です。数と正は(たとして解釈される)と、同じ値を表示します。数と負するとして解釈される大きな正の数です。
した回答までにキャストを求める署名を付けない問題です。のボーダーケース署名の整数は-1(小さいか、0xffffffffバイト).く、奇数を足したり引いたりしたから、すでにキャストできます。
ただし、切ったお肉をミンチにします鋳造後、暗号通信の使用を推奨ン変数であることなどを明らかにしタイプなので、例えば:
int iValue, iResult;
unsigned int uValue, uResult;
ではあまりにも簡単に係り重要な問題を忘れる変数がどのような名前なしのヒント.かしいキャストを符号なしに利用し、その配列として指数です。
何を暗黙的に変換を継続して行っており、今後はここで、
まさに変換符号なし整数です。
このコードは安全のためのすべての値uていただきます。
安心感の定義あり( https://stackoverflow.com/a/50632/5083516 ).
ルールは、通常は難しい規格-語りものであっても本質的には何を表現で使用された署名の整数の符号なし整数値が含まれていますの2の補数表現の多くの注目を集めています。
は、加算、減算、乗算が正しく動作するこれらの番号により他の符号なし整数を含むtwosる補数表現の"実際の結果".
部鋳造が大きくな符号なし整数タイプのいく定義された結果がこれらの実験結果は2の補数表現の"実際の結果".
(安全の意味でもこの例では、オーバーフローの一大正数、キャストでint型のリアルです。
中からの変換を無効にしunsignedによって定義され、標準の逆は実装で定義されています両方のgcc、msvcの定義の変換などの場合は"実績"に変換する時、2の補数に格納されている数値は符号なし整数に戻る符号付き整数です。期待していますぐその他の行動に曖昧にシステムを使用しない2の補完のための署名の整数です。
https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html#Integers-implementation https://msdn.microsoft.com/en-us/library/0eex498h.aspx
恐ろしい答えを三昧
Ozgur Ozcitak
だから締めの符号なし (およびその逆)の内部 表現とはありません 変化します。どのような変化がどのように コンパイラを解釈し、署名ます。
これは完全に間違っています。
マットFredriksson
が符号なしと署名 変数を追加(またはずのバイナリ 操作)は、暗黙のうちに に変換符号なし、 この場合、結果に大きます。
これも間違っています。符号なし整数ではありうことができたときはintうと同等の精度によりパディングビットの符号なしタイプです。
smh
します動作の原因になint 変換する符号なしint.
間違っています。かなともださい。
変換符号なしint値の署名 intは、実装に依存します。( それぞれの作品に期待する ほとんどのプラットフォームです。)
間違っています。では未定義の場合の動作の原因となりオーバーフローまたは値が保存されている。
匿名
の値に変換された unsigned int...
間違っています。より精度のintからの相対unsigned int.
テイラーの価格
した回答でき キャストを求める署名 符号なしな問題です。
間違っています。う店値の範囲外で署名された整数値結果が未定義です。
すことができなかったが最後に回答の問題をもたらしていました。
べ、精度のintとunsigned int,uを進める署名されたintときの値を取得します。-4444からの表現(u+i)。現在、uいその他の値はありませんが、できればオーバーフローで未定義の行動も正確な数を取得しま-4444 [1].この値としてint型.もしようとしている店舗価値が符号なしintとしてのキャストを符号なしint値する結果とう(UINT_MAX+1)-4444.
べ、精度のunsigned intするよりも、int、署名したintを推進するunsigned int降伏値(UINT_MAX+1)-5678追加されるその他の符号なしint1234.すべuいその他の値の表現以外の範囲{0..UINT_MAX}の値(UINT_MAX+1)は追加または減算までの結果は秋の範囲{0..UINT_MAX)と定義されていない動作が発生します。
何精密?
整数てのパディングビット符号ビット、および値ですね。符号なし整数でないサビも.Unsigned charには更に保証されないパディングビット.値の数ビットの整数値がどのくらいの精度です。
[Gotchas]
マクロsizeofマクロで使用できませんの決定精度の整数の場合のパディングバッファと出力バッファの両方が存在する。のサイズをバイトでなくて、octet(最上位ビット)として定義されるC99.
[1] のオーバーフローの発生する可能性の一つのポイントがあります。のいずれかの前に、中推進)-きunsigned intが大きすぎるサイズ調整する場合もあるのでint.のオーバーフローが発生した後の場合においてもunsigned intたintの範囲のほかの結果がオーバーフロー.
に関係のない、私は最近大学院生として作;)