tetl
0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
midpoint.hpp
Go to the documentation of this file.
1
// SPDX-License-Identifier: BSL-1.0
2
// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch
3
#
ifndef
TETL_NUMERIC_MIDPOINT_HPP
4
#
define
TETL_NUMERIC_MIDPOINT_HPP
5
6
#
include
<
etl
/
_concepts
/
floating_point
.
hpp
>
7
#
include
<
etl
/
_cstddef
/
ptrdiff_t
.
hpp
>
8
#
include
<
etl
/
_limits
/
numeric_limits
.
hpp
>
9
#
include
<
etl
/
_numeric
/
abs
.
hpp
>
10
#
include
<
etl
/
_type_traits
/
is_integral
.
hpp
>
11
#
include
<
etl
/
_type_traits
/
is_pointer
.
hpp
>
12
#
include
<
etl
/
_type_traits
/
is_same
.
hpp
>
13
#
include
<
etl
/
_type_traits
/
make_unsigned
.
hpp
>
14
15
namespace
etl
{
16
17
/// \brief Returns half the sum of a + b. If the sum is odd, the result is
18
/// rounded towards a.
19
///
20
/// \details CppCon 2019: Marshall Clow "midpoint? How Hard Could it Be?"
21
/// Integer version was updated to match implementation from libc++.
22
///
23
/// https://www.youtube.com/watch?v=sBtAGxBh-XI)
24
/// https://en.cppreference.com/w/cpp/numeric/midpoint
25
///
26
/// \ingroup numeric
27
template
<
typename
Int>
28
requires
(
etl
::is_integral_v<Int>
and
not
etl
::is_same_v<Int,
bool
>)
29
constexpr
auto
midpoint
(Int a, Int b)
noexcept
-> Int
30
{
31
using
UInt =
etl
::make_unsigned_t<Int>;
32
33
auto
const
shift =
static_cast
<UInt>(
etl
::
numeric_limits
<UInt>::digits - 1);
34
auto
const
diff =
static_cast
<UInt>(UInt(b) - UInt(a));
35
auto
const
sign =
static_cast
<UInt>(b < a);
36
auto
const
half =
static_cast
<UInt>((diff / 2) + (sign << shift) + (sign & diff));
37
38
return
a +
static_cast
<Int>(half);
39
}
40
41
/// \ingroup numeric
42
template
<
etl
::floating_point Float>
43
constexpr
auto
midpoint
(Float a, Float b)
noexcept
-> Float
44
{
45
auto
const
lo =
etl
::
numeric_limits
<Float>::min() * 2;
46
auto
const
hi =
etl
::
numeric_limits
<Float>::max() / 2;
47
48
if
(
etl
::abs(a) <= hi
and
etl
::abs(b) <= hi) {
49
return
(a + b) / 2;
50
}
51
if
(
etl
::abs(a) < lo) {
52
return
a + b / 2;
53
}
54
if
(
etl
::abs(b) < lo) {
55
return
a / 2 + b;
56
}
57
58
return
a / 2 + b / 2;
59
}
60
61
/// \ingroup numeric
62
template
<
typename
Ptr>
63
requires
etl
::is_pointer_v<Ptr>
64
constexpr
auto
midpoint
(Ptr a, Ptr b)
noexcept
-> Ptr
65
{
66
return
a +
etl
::midpoint(
etl
::ptrdiff_t(0), b - a);
67
}
68
69
}
// namespace etl
70
71
#
endif
// TETL_NUMERIC_MIDPOINT_HPP
etl::midpoint
constexpr auto midpoint(Int a, Int b) noexcept -> Int
Returns half the sum of a + b. If the sum is odd, the result is rounded towards a.
Definition
midpoint.hpp:29
etl
Definition
adjacent_find.hpp:9
etl::numeric_limits
Definition
numeric_limits.hpp:18
include
etl
_numeric
midpoint.hpp
Generated on Sun Sep 7 2025 19:15:15 for tetl by
1.9.8