std::lerp
Определено в заголовке <cmath> | ||
|---|---|---|
| (1) | ||
constexpr float lerp( float a, float b, float t ) noexcept;
constexpr double lerp( double a, double b, double t ) noexcept;
constexpr long double lerp( long double a, long double b,
long double t ) noexcept; |
(с C++20) (до C++23) | |
constexpr /* floating-point-type */
lerp( /* floating-point-type */ a,
/* floating-point-type */ b,
/* floating-point-type */ t ) noexcept;
| (с C++23) | |
| Дополнительные перегрузки | ||
Определено в заголовке <cmath> | ||
template< class Arithmetic1, class Arithmetic2, class Arithmetic3 >
constexpr /* common-floating-point-type */
lerp( Arithmetic1 a, Arithmetic2 b, Arithmetic3 t ) noexcept;
| (A) | (с C++20) |
a и b, если параметр t находится внутри [0, 1) (в противном случае – линейную экстраполяцию), т. е. результат \(a+t(b−a)\)a+t(b−a) с учётом неточностей вычислений с плавающей точкой. Библиотека предоставляет перегрузки для всех типов чисел с плавающей точкой без cv-квалификаторов в качестве типов параметров a, b и t. (с C++23)
Параметры
| a, b, t | - | значения с плавающей точкой или целые |
Возвращаемое значение
\(a + t(b − a)\)a + t(b − a)
Когда std::isfinite(a) && std::isfinite(b) равно true, гарантируются следующие свойства:
- Если
t == 0, результат равенa. - Если
t == 1, результат равенb. - Если
t >= 0 && t <= 1, результат конечен. - Если
std::isfinite(t) && a == b, результат равенa. - Если
std::isfinite(t) || (b - a != 0 && std::isinf(t)), результат не являетсяNaN.
Пусть CMP(x, y) равно 1 если x > y, -1 если x < y, и 0 в противном случае. Для любых t1 и t2, произведение
-
CMP(std::lerp(a, b, t2), std::lerp(a, b, t1)), -
CMP(t2, t1), и -
CMP(b, a)
неотрицательно. (То есть, std::lerp монотонно возрастает.)
Примечания
Дополнительные перегрузки не требуют точного предоставления, как в (A). Они должны лишь быть достаточными для того, чтобы гарантировать, что для первого аргумента num1, второго аргумента num2 и третьего аргумента num3:
| (до C++23) |
| Если Если такого типа чисел с плавающей точкой с наибольшим рангом и подрангом не существует, тогда разрешение перегрузок не приводит к пригодной кандидатуре из предоставляемых перегрузок. | (с C++23) |
| Макрос проверки наличия функции | Значение | Стандарт | Функция |
|---|---|---|---|
__cpp_lib_interpolate | 201902L | (C++20) |
std::lerp, std::midpoint |
Пример
#include <cassert>
#include <cmath>
#include <iostream>
float naive_lerp(float a, float b, float t)
{
return a + t * (b - a);
}
int main()
{
std::cout << std::boolalpha;
const float a = 1e8f, b = 1.0f;
const float midpoint = std::lerp(a, b, 0.5f);
std::cout << "a = " << a << ", " << "b = " << b << '\n'
<< "midpoint = " << midpoint << '\n';
std::cout << "std::lerp is exact: "
<< (a == std::lerp(a, b, 0.0f)) << ' '
<< (b == std::lerp(a, b, 1.0f)) << '\n';
std::cout << "naive_lerp is exact: "
<< (a == naive_lerp(a, b, 0.0f)) << ' '
<< (b == naive_lerp(a, b, 1.0f)) << '\n';
std::cout << "std::lerp(a, b, 1.0f) = " << std::lerp(a, b, 1.0f) << '\n'
<< "naive_lerp(a, b, 1.0f) = " << naive_lerp(a, b, 1.0f) << '\n';
assert(not std::isnan(std::lerp(a, b, INFINITY))); // lerp here can be -inf
std::cout << "Extrapolation demo, given std::lerp(5, 10, t):\n";
for (auto t{-2.0}; t <= 2.0; t += 0.5)
std::cout << std::lerp(5.0, 10.0, t) << ' ';
std::cout << '\n';
}Возможный вывод:
a = 1e+08, b = 1 midpoint = 5e+07 std::lerp is exact?: true true naive_lerp is exact?: true false std::lerp(a, b, 1.0f) = 1 naive_lerp(a, b, 1.0f) = 0 Extrapolation demo, given std::lerp(5, 10, t): -5 -2.5 0 2.5 5 7.5 10 12.5 15
См. также
|
(C++20) | Середина между двумя числами или указателями (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/numeric/lerp