numeric_midpoint

numeric_midpoint (중간값)

std::midpoint은 정수, 부동소수점 또는 포인터 a와 b의 중간값을 계산하는 함수예요. 오버플로 없이 계산해요. C++20부터 사용할 수 있어요.

출처: cppreference

본문

<numeric> 헤더에 정의되어 있고, 시그니처는 다음과 같아요.

template< class T >
constexpr T midpoint( T a, T b ) noexcept;

(1) (since C++20)

template< class T >
constexpr T* midpoint( T* a, T* b );

(2) (since C++20)

정수, 부동소수점 또는 포인터 a와 b의 중간값을 계산해요.

    1. 이 오버로드는 T가 bool이 아닌 산술 타입일 때만 오버로드 해석에 참여해요.
    1. 이 오버로드는 T가 객체 타입일 때만 오버로드 해석에 참여해요. T가 불완전 타입이면 사용이 ill-formed예요.

매개변수 (Parameters)

  • a, b — 정수, 부동소수점 또는 포인터 값

반환값 (Return value)

    1. a와 b의 합의 절반. 오버플로가 없어요. a와 b가 정수 타입이고 합이 홀수이면 결과는 a 방향으로 반올림돼요. a와 b가 부동소수점 타입이면 부정확한 연산이 최대 한 번 일어나요.
    1. a와 b가 각각 같은 배열 객체 x의 x[i]와 x[j]를 가리키면(포인터 산술 목적), x[i + (j - i) / 2]를 가리키는 포인터를 반환해요(또는 동등하게 x[std::midpoint(i, j)]). 여기서 나눗셈은 0 방향으로 반올림돼요. a와 b가 같은 배열 객체의 요소를 가리키지 않으면 동작은 정의되지 않아요.

예외 (Exceptions)

예외를 던지지 않아요.

참고 (Notes)

오버로드 (2)는 흔한 플랫폼에서 return a + (b - a) / 2;로 간단히 구현할 수 있어요. 하지만 그런 구현은 이식성이 보장되지 않아요. PTRDIFF_MAX보다 많은 요소를 가진 배열을 만드는 것이 가능한 플랫폼이 있을 수 있고, b와 a가 모두 같은 배열의 요소를 가리켜도 b - a가 정의되지 않은 동작을 낳을 수 있기 때문이에요.

피처 테스트 매크로 표준 기능
__cpp_lib_interpolate 201902L (C++20) std::lerp, std::midpoint

예제 (Example)

이 코드를 실행해 봐요.

#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): 4294967294
Correct: 4294967294

std::midpoint('2', '4'): '3'
std::midpoint('2', '5'): '3'
std::midpoint('5', '2'): '3'
std::midpoint('2', '6'): '4'

더 알아보기 (Learn more)

cppreference