数値の上限とオーバーフローの動作
std::numeric_limitsを調べ、符号付き整数と符号なし整数のオーバーフロー規則を理解します。
「数値の上限とオーバーフローの動作」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。
上限と下限が重要な理由
すべての数値型には、表現できる最大値と最小値があります。これらを超えると、気付かないうちに誤った結果になったり、未定義動作が発生したりする可能性があります。
std::numeric_limits
<limits> ヘッダーを使うと、任意の数値型の上限と下限を問い合わせることができます。コンパイル時定数なので、実行時のコストはありません。
#include <limits>
std::cout << std::numeric_limits<int>::max() << "\n";
std::cout << std::numeric_limits<int>::min() << "\n";
std::cout << std::numeric_limits<double>::epsilon();よく使う問い合わせ
特に便利なメンバーは次のとおりです。
max()— 最大値min()— 最小の正の値lowest()— 最も小さい値epsilon()— 意味のある最小の差(浮動小数点数)digits10— 保証される10進数の桁数
符号付き整数のオーバーフロー
符号付き整数のオーバーフローは未定義動作です。コンパイラーはオーバーフローが起きないと仮定できるため、予想外の最適化につながる場合があります。
int x = std::numeric_limits<int>::max();
x += 1; // UB — anything can happen符号なし整数のラップアラウンド
符号なし整数のオーバーフローは定義済みです。値は 2^N を法とした剰余として循環します。便利な場合もありますが、バグの原因になることも多くあります。
unsigned int u = 0;
u -= 1; // wraps to 4,294,967,295 (UINT_MAX)浮動小数点数のオーバーフローとアンダーフロー
浮動小数点数はクラッシュする代わりに inf へオーバーフローします。アンダーフローすると、非正規化数または 0 になります。
double x = 1e308;
x *= 100;
std::cout << x; // inf安全にオーバーフローを検出する
符号付き整数では、演算の前にチェックしてください。コンパイラーには、GCC/Clang の __builtin_add_overflow のような、オーバーフローをチェックする組み込みヘルパーがあります。
if (a > std::numeric_limits<int>::max() - b) {
// overflow would happen
}
int sum = a + b;C++20 の std::ssize と std::cmp_less
C++20 では、<utility> に安全な整数比較ヘルパーが追加されました。std::cmp_equal、cmp_less、cmp_greater などがあり、符号付き整数と符号なし整数の混在を正しく処理します。
暗黙の変換は気付きにくい
比較で符号付き整数と符号なし整数を混在させると、符号付きのオペランドが暗黙に符号なしへ変換されます。これは微妙なバグのよくある原因です。
int a = -1;
unsigned int b = 1;
if (a < b) std::cout << "yes";
else std::cout << "no"; // prints "no"!コンパイル時チェック
移植性のあるコードを書くときは、static_assert を使ってサイズに関する前提条件を保証してください。
static_assert(sizeof(int) >= 4, "Need at least 32-bit int");テストではサニタイザーが役立つ
-fsanitize=undefined を指定してビルドすると、テスト中の実行時に符号付き整数のオーバーフローを検出できます。
g++ -fsanitize=undefined -O1 main.cpp理解度チェック
C++ で符号付き整数の加算がオーバーフローすると、何が起こりますか。
まとめ
std::numeric_limits を使って、型の上限と下限を確認してください。符号付き整数のオーバーフローは未定義動作で、符号なし整数は循環します。符号付き整数と符号なし整数を混在させると危険です。サニタイザーと C++20 の安全な比較機能がコードを守るのに役立ちます。
よくある質問
「数値の上限とオーバーフローの動作」レッスンは無料ですか?
はい。「数値の上限とオーバーフローの動作」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。
「数値の上限とオーバーフローの動作」で何を学びますか?
std::numeric_limitsを調べ、符号付き整数と符号なし整数のオーバーフロー規則を理解します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C++ Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「数値の上限とオーバーフローの動作」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC++ Academyレッスンでコードを書いて実行できますか?
はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 整数型と浮動小数点型
- cmathヘッダー:pow、sqrt、abs、round
- randomヘッダーで乱数を扱う
- 数値の上限とオーバーフローの動作