はじめに
C++で、2つの数値のちょうど真ん中の値(中間点)や、2点間を滑らかにつなぐ途中の値を求めたい場合があります。
C++20では、これらの計算を安全かつ効率的に行うための、標準的な数学関数が <cmath>
ヘッダーに追加されました。
std::midpoint
: 2つの値の中間点を、オーバーフローを考慮して安全に計算する。std::lerp
: 2つの値の間を、指定した割合で**線形補間(Linear Interpolation)**する。
この記事では、これら2つの新しい関数の使い方を解説します。
【前提】C++20とは?
C++20は、2020年に正式化されたC++言語のメジャーアップデート版です。この記事で紹介する機能はC++20で導入されたため、利用するにはC++20に対応したコンパイラが必要です。
1. std::midpoint
: 2つの値の中間点を求める
std::midpoint(a, b)
は、2つの値 a
と b
の中間点を計算します。単純に (a + b) / 2
と計算するのと似ていますが、a + b
がオーバーフロー(数値型が表現できる最大値を超えてしまうこと)を起こすような極端に大きな値の場合でも、安全に正しい結果を計算できるように設計されています。
サンプルコード
#include <iostream>
#include <numeric> // midpoint, lerp (C++20)
using namespace std;
int main() {
// 整数の場合
cout << "midpoint(10, 20): " << midpoint(10, 20) << endl;
// 小数の場合
cout << "midpoint(5.0, 8.0): " << midpoint(5.0, 8.0) << endl;
// ポインタの場合 (配列の中央を指すポインタ)
int arr[] = {11, 22, 33, 44, 55};
int* p_mid = midpoint(arr, arr + 4);
cout << "配列の中央の値: " << *p_mid << endl;
return 0;
}
2. std::lerp
: 2点間の線形補間
std::lerp(a, b, t)
は、値 a
と b
の間を、t
の割合で線形補間した値を返します。lerp
は Linear Interpolation の略です。
t = 0.0
のとき、a
を返します。t = 1.0
のとき、b
を返します。t = 0.5
のとき、a
とb
の中間点(midpoint
と同じ結果)を返します。
ゲームプログラミングでオブジェクトを滑らかに動かしたり、データ視覚化で色のグラデーションを作成したりする際などに広く使われます。
サンプルコード
#include <iostream>
#include <numeric> // midpoint, lerp (C++20)
#include <iomanip> // fixed, setprecision
using namespace std;
int main() {
double start_point = 100.0;
double end_point = 200.0;
cout << fixed << setprecision(1); // 小数点以下1桁表示に設定
cout << "--- 100.0 から 200.0 へ線形補間 ---" << endl;
// 0.0 (0%) から 1.0 (100%) まで、0.25 (25%) 刻みで補間
for (double t = 0.0; t <= 1.0; t += 0.25) {
cout << "割合 " << t << ": " << lerp(start_point, end_point, t) << endl;
}
return 0;
}
実行結果
--- 100.0 から 200.0 へ線形補間 ---
割合 0.0: 100.0
割合 0.2: 125.0
割合 0.5: 150.0
割合 0.8: 175.0
割合 1.0: 200.0
まとめ
今回は、C++20で導入された2つの便利な数学関数、std::midpoint
と std::lerp
を解説しました。
std::midpoint(a, b)
:a
とb
の中間点を安全に計算する。std::lerp(a, b, t)
:a
とb
の間をt
の割合で線形補間する。
これらの標準関数を使うことで、従来は手動で実装する必要があった数値計算を、より安全かつ簡潔に記述することができます。