整数が容量に達しているかどうかをテストすることは、コードが非常に非効率になることを意味します。たとえば、123を追加するには、123の増分と123の比較を行う必要があります。
より良い方法は、操作を実行する前に、操作がオーバーフローするかどうかを判断することです。例(符号なし整数の場合のみ):
if(sum <= ULLONG_MAX - a) {
sum += a;
} else {
/* It would have overflowed */
}
ULLONG_MAX - a
オーバーフローできないため、これは機能します。符号付き整数を調べ始めると、オーバーフローする可能性がありLLONG_MAX - a
(a
負の場合)、LLONG_MIN - a
オーバーフローする可能性がある(正の場合)ため、より大きな問題になりa
ます。両方の方法をテストする必要があります。
if( ( a > 0) && (sum <= LLONG_MAX - a) {
sum += a;
} else if( ( a < 0) && (sum >= LLONG_MIN - a) {
sum += a;
} else if( a != 0) {
/* It would have overflowed */
}
オーバーフローしたかどうかを判断したら、そのケースを処理する必要があります。例えば; 1つの大きな整数を表すために複数の整数を使用している場合。次に(符号なし整数の場合):
if(sum_low <= ULLONG_MAX - a) {
sum_low += a;
} else {
sum_low -= (ULLONG_MAX - a) + 1;
sum_high++;
}
元の(回避された)オーバーフローの処理に関連する一時的な計算で偶発的なオーバーフローを回避するために、非常に注意する必要があることに注意してください。
複数の符号付き整数を使用して1つの大きな符号付き整数を表す場合、オーバーフロー処理の背後にあるロジックは複雑になり、エラーが発生しやすくなります。理論的には可能です。ただし、数値の符号を分離してから、符号なし整数のみに対して演算(またはその逆-たとえば、負の数を加算する代わりに正の数を減算する)を実行する方がはるかに優れています。特に、1つの巨大な整数を表すために3つ以上の整数を使用する必要がある場合、または乗算や除算などのより複雑な演算が必要な場合。
もちろん、このパスを開始すると、独自の「大きな数」のコードを効果的に実装しているので、代わりに適切なライブラリを見つけて使用する必要があります。
最後に、新しいデータ型をプリミティブデータ型のように扱いたい場合(たとえば、のようなことができる場合mydatatype a = 0;
)、運が悪いです-Cはこのようには機能しません。基本的に、Cは、コードを読んだり理解したりしようとする人々から複雑なものを隠すことができないため、美しいものです。また、疑いを持たない被害者から重要な情報を隠したい場合は、C++のようなあまり美しくない言語を使用する必要があります。;-)