次の計算結果は「1」です。
unsigned long iEndFrame = ((4294966336 + 1920 - 1) / 1920) + 1;
誰かが理由を見ますか?これなら対応できると思いunsigned long
ました。
助けてくれてありがとう。
計算の右側の値のタイプはunsigned int
orint
です。
4294966336 + 1920 = 4294968256
と仮定sizeof(unsigned int) == 4
すると、これはオーバーフローし、960
(960-1)/1920 = 0
(整数演算での丸めのため)。これにより、
0 + 1 = 1
より大きな型を使用して計算を実行する場合 (および を想定sizeof(unsigned long) > sizeof(unsigned int)
)、計算内でキャストする必要があります。
unsigned long iEndFrame = (((unsigned long)4294966336 + 1920 - 1) / 1920) + 1;
または、Slavaが指摘したように、リテラル値の1つをサフィックスunsigned long
を使用して型に設定しますUL
unsigned long iEndFrame = ((4294966336UL + 1920 - 1) / 1920) + 1;
「unsigned long でこれを処理できると思いました。」- これが何を意味するのかわかりません。評価する式には、 を使用する必要があることを示唆するものは何もありませんunsigned long
。最終的にunsigned long
変数を初期化しても、評価のプロセスには影響しません。初期化式はそれとは完全に独立して処理されます。
現在、C++ 言語では、サフィックスのない 10 進整数リテラルには常に符号付きの型があります。コンパイラは、式で使用されるリテラルに対して符号なしの型を選択することはできません。コンパイラは、リテラルの値に応じてint
、long int
またはlong long int
(最後のもの - C++11) を使用する必要があります。コンパイラは、実装依存の拡張整数型を使用できますが、それらが署名されている場合に限ります。また、すべての符号付き型が小さすぎると、プログラムの動作が未定義になります。
「従来の」16、32、または 64 ビット幅の整数型を持つ典型的な実際のプラットフォームで作業していると仮定すると、ここには 2 つの可能性しかありません。
プラットフォーム上ですべての符号付き整数型が小さすぎて表現できない4294966336
場合、プログラムは未定義の動作をします。話の終わり。
少なくとも 1 つの符号付き整数型が に対して十分な大きさ4294966336
である場合、評価のオーバーフローは発生せず、式は と評価され2236963
ます。
したがって、その結果についての唯一の実際の言語レベルの説明は、1
未定義の動作に遭遇しているということです。これは、すべての符号付き型が小さすぎて、式で使用したリテラルを表すことができないためです。
お使いのプラットフォームで、符号付き整数型が実際に表現するのに十分な大きさ4294966336
(つまり、少なくとも 64 ビットの型がある) である場合、その結果は、コンパイラが壊れているという事実によってのみ説明できます。
PSunsigned int
評価に使用される可能性があるのは、古い C 言語 - C89/90 のみであることに注意してください。これにより、得られた結果の 3 番目の説明が生成されます。しかし、繰り返しになりますが、その説明は C89/90 コンパイラにのみ適用され、C++ コンパイラや C99 コンパイラには適用されません。あなたの質問には [C++] というタグが付けられています。
これをコメントとして残すつもりでしたが、十分な評判がありません。とにかくこれを共有したかったのは、tmighty の質問には 2 つの要素があり、そのうちの 1 つは正確に答えられない可能性があるためです。
あなたはすでに「unsigned longでこれを処理できると思った」と述べており、他の回答はこれを確認しているようですが、私が知っていることから-そして確認するために今すぐ再確認してください-unsigned long
十分な大きさではない可能性があります. 少なくとも4294967295
であることが保証されていますが、これはユース ケースには小さすぎます。具体的には、VC++ を使用して Windows でチェックしたところ、32 ビットと 64 ビットの両方のコンパイルで ULONG_MAX が と定義されています4294967295
。
代わりに、「ULL」サフィックスを使用して を使用する必要がある場合があります。unsigned long long
その最大値は少なくとも18446744073709551615
. 目的に十分な大きさであると定義されているプラットフォームがあったとしても、unsigned long
十分な大きさであることが実際に保証されているデータ型を使用したい場合があると思います。