Namespaces
Variants

std:: midpoint

From cppreference.net
Определено в заголовке <numeric>
template < class T >
constexpr T midpoint ( T a, T b ) noexcept ;
(1) (начиная с C++20)
template < class T >
constexpr T * midpoint ( T * a, T * b ) ;
(2) (начиная с C++20)

Вычисляет среднюю точку для целых чисел, чисел с плавающей запятой или указателей a и b .

1) Эта перегрузка участвует в разрешении перегрузки только если T является арифметическим типом, отличным от bool .
2) Эта перегрузка участвует в разрешении перегрузки только если T является объектным типом. Использование этой перегрузки некорректно, если T является неполным типом .

Содержание

Параметры

a, b - целые числа, числа с плавающей точкой или указатели

Возвращаемое значение

1) Полусумма a и b . Переполнения не происходит. Если a и b имеют целочисленный тип и сумма нечётная, результат округляется в сторону a . Если a и b имеют тип с плавающей запятой, происходит не более одной неточной операции.
2) Если a и b указывают соответственно на x [ i ] и x [ j ] одного и того же объекта массива x (для целей арифметики указателей ), возвращает указатель на x [ i + ( j - i ) / 2 ] (или, эквивалентно, x [ std :: midpoint ( i, j ) ] ), где деление выполняется в сторону нуля. Если a и b не указывают на элементы одного и того же объекта массива, поведение не определено.

Исключения

Не генерирует исключений.

Примечания

Перегрузка (2) может быть просто реализована как return a + ( b - a ) / 2 ; на распространённых платформах. Однако такая реализация не гарантирует переносимости, поскольку могут существовать платформы, где создание массива с количеством элементов, превышающим PTRDIFF_MAX возможно, и b - a может привести к неопределённому поведению, даже если оба указателя b и a указывают на элементы одного массива.

Макрос тестирования возможностей Значение Стандарт Возможность
__cpp_lib_interpolate 201902L (C++20) std::lerp , std::midpoint

Пример

#include <cstdint>
#include <iostream>
#include <limits>
#include <numeric>
int main()
{
    std::uint32_t a = std::numeric_limits<std::uint32_t>::max();
    std::uint32_t b = std::numeric_limits<std::uint32_t>::max() - 2;
    std::cout << "a: " << a << '\n'
              << "b: " << b << '\n'
              << "Некорректно (переполнение и перенос): " << (a + b) / 2 << '\n'
              << "Корректно: " << std::midpoint(a, b) << "\n\n";
    auto on_pointers = [](int i, int j)
    {
        char const* text = "0123456789";
        char const* p = text + i;
        char const* q = text + j;
        std::cout << "std::midpoint('" << *p << "', '" << *q << "'): '"
                  << *std::midpoint(p, q) << "'\n";
    };
    on_pointers(2, 4);
    on_pointers(2, 5);
    on_pointers(5, 2);
    on_pointers(2, 6);
}

Вывод:

a: 4294967295
b: 4294967293
Incorrect (overflow and wrapping): 2147483646
Correct: 4294967294
std::midpoint('2', '4'): '3'
std::midpoint('2', '5'): '3'
std::midpoint('5', '2'): '4'
std::midpoint('2', '6'): '4'

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2024):
  • 27.10.16 Середина [numeric.ops.midpoint]
  • Стандарт C++20 (ISO/IEC 14882:2020):
  • 25.10.15 Середина [numeric.ops.midpoint]

Смотрите также

(C++20)
функция линейной интерполяции
(функция)