タグ付けされた質問 「integer-overflow」

整数オーバーフローは、演算の結果が、基になる整数型で表すことができる最大値よりも大きい場合に発生します。

30
符号なし整数乗算オーバーフローを検出するにはどうすればよいですか?
OverаэтотвопросестьответынаStack Overflowнарусском:МожнолинаязыкахC / C ++определитьцелочисленнееленееленее 私は、すべての解決策を見つけるためにC ++でプログラムを書いていたB = C、、BとCが一緒にすべての桁を使用し0-9回だけを。プログラムは、値の上にループとB、そして、それは上の桁カウントルーチンを毎回走っ、BとBの桁条件が満たされたかどうかを確認します。 しかし、スプリアス溶液を生成することができるbは整数制限をオーバーフロー。私は次のようなコードを使用してこれをチェックすることになりました: unsigned long b, c, c_test; ... c_test=c*b; // Possible overflow if (c_test/b != c) {/* There has been an overflow*/} else c=c_test; // No overflow オーバーフローをテストするより良い方法はありますか?一部のチップにはオーバーフローが発生したときに設定される内部フラグがあることは知っていますが、CまたはC ++を介してアクセスされることはありません。 符号付き intオーバーフローはCおよびC ++では未定義の動作であるため、実際にそれを引き起こさずに検出する必要があることに注意してください。追加前の署名付きintオーバーフローについては、C / C ++での署名付きオーバーフローの検出を参照してください。
618 c++  c  integer-overflow 

4
(-2147483648> 0)C ++ではtrueを返しますか?
-2147483648は32ビットの整数型の最小の整数ですが、if(...)文中でオーバーフローするようです: if (-2147483648 > 0) std::cout << "true"; else std::cout << "false"; これはtrue私のテストで印刷されます。ただし、-2147483648を整数にキャストすると、結果は異なります。 if (int(-2147483648) > 0) std::cout << "true"; else std::cout << "false"; これは印刷されますfalse。 よくわかりません。誰でもこれについて説明できますか? 2012年2月5日更新: コメントありがとうございます。私のコンパイラでは、intのサイズは4バイトです。いくつかの簡単なテストにVCを使用しています。質問の説明を変更しました。 すなわち、この記事では非常に良いreplysがたくさんだ、AndreyTは非常に詳細な入力にどのようにコンパイラの意志行動に説明し、どのようにこの最小の整数が実装されましたを与えました。一方、qPCR4virは、いくつかの関連する「好奇心」と、整数の表現方法を提供しました。とても印象的です!


5
なぜ符号なし整数オーバーフローは動作が定義されていますが、符号付き整数オーバーフローは定義されていないのですか?
符号なし整数オーバーフローは、CおよびC ++標準の両方で明確に定義されています。たとえば、C99標準(§6.2.5/9)は 結果の符号なし整数型で表すことができない結果は、結果の型で表すことができる最大値よりも1大きい数を法として減じられるため、符号なしオペランドを伴う計算は決してオーバーフローできません。 ただし、どちらの規格も、符号付き整数オーバーフローは未定義の動作であると述べています。ここでも、C99標準(§3.4.3/1)から 未定義の動作の例は、整数オーバーフローでの動作です この矛盾の歴史的または(さらに良い!)技術的な理由はありますか?

30
インタープリター言語で非常に大きな整数を処理するときに予期しない結果が発生する
私は合計を取得しようとしています1 + 2 + ... + 1000000000が、PHPとNode.jsで面白い結果を得ています。 PHP $sum = 0; for($i = 0; $i <= 1000000000 ; $i++) { $sum += $i; } printf("%s", number_format($sum, 0, "", "")); // 500000000067108992 Node.js var sum = 0; for (i = 0; i <= 1000000000; i++) { sum += i ; } …

15
exprでオーバーフローを回避する方法。あいうえお
:私はのように見える表現を計算する必要があり A*B - C*D、その種類は次のとおりです。signed long long int A, B, C, D; それぞれの数字は(その型をオーバーフローしない)本当に大きなことができます。一方でA*B、オーバーフローを引き起こす可能性があり、同時に式はA*B - C*D本当に小さくすることができます。どうすれば正しく計算できますか? 例:MAX * MAX - (MAX - 1) * (MAX + 1) == 1、ここでMAX = LLONG_MAX - n、n-ある自然数。
161 c++  c  integer-overflow 


6
(A + B + C)≠(A + C + B)とコンパイラの並べ替え
2つの32ビット整数を追加すると、整数オーバーフローが発生する可能性があります。 uint64_t u64_z = u32_x + u32_y; このオーバーフローは、32ビット整数の1つが最初にキャストされるか、64ビット整数に追加される場合に回避できます。 uint64_t u64_z = u32_x + u64_a + u32_y; ただし、コンパイラが追加の順序を変更することを決定した場合: uint64_t u64_z = u32_x + u32_y + u64_a; それでも整数オーバーフローが発生する可能性があります。 コンパイラはそのような並べ替えを行うことができますか、それとも、結果の矛盾に気づき、式の順序をそのまま維持することを信頼できますか?

14
Javaで2つの数値を乗算するとオーバーフローが発生するかどうかを確認するにはどうすればよいですか?
2つの数値を乗算するとオーバーフローが発生するという特殊なケースを処理したいと思います。コードは次のようになります。 int a = 20; long b = 30; // if a or b are big enough, this result will silently overflow long c = a * b; これは簡易バージョンです。実際のプログラムaでbは、実行時に他の場所から供給されます。私が達成したいのは次のようなものです: long c; if (a * b will overflow) { c = Long.MAX_VALUE; } else { c = a * b; } …

8
実装定義の動作を回避する効率的な符号なしから符号付きのキャスト
unsigned intas引数を取り、intUINT_MAX +1を法とする合同を引数に返す関数を定義したいと思います。 最初の試みは次のようになります。 int unsigned_to_signed(unsigned n) { return static_cast<int>(n); } しかし、言語弁護士なら誰でも知っているように、INT_MAXより大きい値の符号なしから符号付きへのキャストは、実装によって定義されます。 (a)仕様で義務付けられている動作のみに依存するようにこれを実装したいと思います。(b)最新のマシンおよび最適化コンパイラでno-opにコンパイルされます。 奇妙なマシンに関しては... unsignedintに対してUINT_MAX + 1を法とするsignedint合同がない場合、例外をスローしたいとしましょう。複数ある場合(これが可能かどうかはわかりません)、最大のものが必要だとしましょう。 OK、2回目の試行: int unsigned_to_signed(unsigned n) { int int_n = static_cast<int>(n); if (n == static_cast<unsigned>(int_n)) return int_n; // else do something long and complicated } 私の謙虚な意見ではありそうもないので、私が典型的な2の補数システムを使用していないときは、効率についてはあまり気にしません。そして、私のコードが2050年の遍在する符号と大きさのシステムのボトルネックになった場合、誰かがそれを理解して最適化できるに違いありません。 さて、この2回目の試みは、私が望むものにかなり近いものです。キャスト先intは一部の入力に対して実装定義ですが、キャストバック先unsignedはUINT_MAX +1を法とする値を保持するために標準によって保証されています。したがって、条件付きは私が望むものを正確にチェックし、私が遭遇する可能性のあるどのシステムでもコンパイルされません。 ただし...int実装定義の動作を呼び出すかどうかを最初に確認せずに、まだキャストしています。2050年のいくつかの架空のシステムでは、誰が何を知っているかを実行できます。だから私はそれを避けたいとしましょう。 質問:私の「3回目の試み」はどのように見えるべきですか? 要約すると、私はしたい: unsignedintからsignedintにキャストします 値modUINT_MAX +1を保持します 標準で義務付けられている動作のみを呼び出す …

12
ループのどの時点で整数オーバーフローは未定義の動作になりますか?
これは、ここに投稿できないはるかに複雑なコードを含む私の質問を説明するための例です。 #include <stdio.h> int main() { int a = 0; for (int i = 0; i < 3; i++) { printf("Hello\n"); a = a + 1000000000; } } このプログラムにはa、3番目のループでオーバーフローするため、プラットフォームでの未定義の動作が含まれています。 それにより、プログラム全体の動作が未定義になりますか、それともオーバーフローが実際に発生したですか?コンパイラは、潜在的にそれが出て仕事ができるa だろう、それは未定義ループ全体を宣言し、彼らはすべてのオーバーフローが起こる前にもかかわらず、printfを実行する気にすることはできませんので、オーバーフロー? (CとC ++のタグは異なりますが、両方の言語が異なる場合は回答に興味があるためです。)

3
符号付き整数オーバーフローはC ++でも未定義の動作ですか?
ご存知のように、符号付き整数オーバーフローは未定義の動作です。しかし、C ++ 11のcstdintドキュメントには興味深いものがあります。 幅がそれぞれ正確に8、16、32、64ビットで、パディングビットがなく、負の値に2の補数を使用する符号付き整数型(実装が型を直接サポートしている場合にのみ提供) リンクを見る そして、ここに私の質問があります:標準では、、、および負の数は2の補数であると明示的に述べられているint8_tのでint16_t、これらのタイプのオーバーフローは未定義の動作ですか?int32_tint64_t 編集私はC ++ 11とC11標準をチェックしました、そしてここに私が見つけたものがあります: C ++ 11、§18.4.1: ヘッダーは、C標準の7.20と同じように、すべての関数、タイプ、およびマクロを定義します。 C11、§7.20.1.1: typedef名はintN_t、幅N、パディングビットなし、2の補数表現の符号付き整数型を指定します。したがって、int8_tは、正確に8ビットの幅を持つそのような符号付き整数型を示します。

4
オンラインIDEで奇妙な動作をするプログラム
私は以下のC ++プログラム(ソース)に出くわしました: #include <iostream> int main() { for (int i = 0; i < 300; i++) std::cout << i << " " << i * 12345678 << std::endl; } それは単純なプログラムのように見え、私のローカルマシンで正しい出力を提供します。 0 0 1 12345678 2 24691356 ... 297 -628300930 298 -615955252 299 -603609574 ただし、codechefなどのオンラインIDEでは、次の出力が得られます。 0 0 1 12345678 2 24691356 …

12
C / C ++での署名付きオーバーフローの検出
一見すると、この質問は整数オーバーフローを検出する方法の複製のように見えるかもしれません。ただし、実際には大幅に異なります。 符号なし整数オーバーフローの検出は非常に簡単ですが、C / C ++での符号付きオーバーフローの検出は実際にはほとんどの人が考えるよりも難しいことがわかりました。 それを行う最も明白でありながら素朴な方法は、次のようになります。 int add(int lhs, int rhs) { int sum = lhs + rhs; if ((lhs >= 0 && sum < rhs) || (lhs < 0 && sum > rhs)) { /* an overflow has occurred */ abort(); } return sum; } これに伴う問題は、C標準によれば、符号付き整数オーバーフローは 未定義の動作であるということです。 言い換えると、標準によれば、符号付きオーバーフローが発生するとすぐに、プログラムはnullポインターを逆参照した場合と同じように無効になります。したがって、上記の事後条件チェックの例のように、未定義の動作を引き起こして、事後にオーバーフローを検出しようとすることはできません。 上記のチェックは多くのコンパイラで機能する可能性がありますが、信頼することはできません。実際、C標準では符号付き整数オーバーフローは未定義であるとされているため、一部のコンパイラ(GCCなど)は上記のチェックを最適化します。、最適化フラグが設定されると、符号付きオーバーフローは不可能であると想定するため、を最適化します。これにより、オーバーフローをチェックする試みが完全に中断されます。 …

5
Java整数compareTo()-なぜ比較と減算を使用するのですか?
私は見つけたjava.lang.Integerの実装compareToは次のような方法のルックスを: public int compareTo(Integer anotherInteger) { int thisVal = this.value; int anotherVal = anotherInteger.value; return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1)); } 問題は、なぜ減算の代わりに比較を使用するのかということです。 return thisVal - anotherVal;

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.