Spec-Zone.ru › C++

std::midpoint

Определено в заголовке <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 указывают на элементы одного и того же массива.

Макрос проверки наличия функции Значение Std Функция
__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'
              << "Incorrect (overflow and wrapping): " << (a + b) / 2 << '\n'
              << "Correct: " << 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:2023):
    • 27.10.16 Средняя точка [numeric.ops.midpoint]
  • Стандарт C++20 (ISO/IEC 14882:2020):
    • 25.10.15 Средняя точка [numeric.ops.midpoint]

См. также

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/numeric/midpoint

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API