libfxd 0.2.dev
A fixed-point library for C++.
Loading...
Searching...
No Matches
conversions.hpp
Go to the documentation of this file.
1/*
2 * libfxd - a fixed-point library for C++
3 *
4 * Copyright 2023 Daniel K. O.
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef LIBFXD_CONVERSIONS_HPP
9#define LIBFXD_CONVERSIONS_HPP
10
11#include <cmath>
12#include <concepts>
13#include <new> // launder()
14#include <type_traits>
15
16#include "concepts.hpp"
17#include "casting.hpp"
18
19#include "detail/bias.hpp"
20#include "detail/int_to_float.hpp"
21#include "detail/shift.hpp"
22
23
24namespace fxd {
25
26
27 template<int Int,
28 int Frac,
29 typename Raw>
30 [[nodiscard]]
31 constexpr
33 const noexcept
34 {
35 return raw_value;
36 }
37
38
40 template<std::integral I,
41 fixed_point Fxd>
42 [[nodiscard]]
43 constexpr
44 I
45 to_int(Fxd f)
46 noexcept
47 {
48 using Raw = typename Fxd::raw_type;
49 Raw raw = f.raw_value;
50 if constexpr (Fxd::frac_bits >= 0) {
51
52 if (raw < 0)
53 raw += detail::make_bias_for(Fxd::frac_bits, raw);
54 return detail::shr_real(raw, Fxd::frac_bits);
55
56 } else {
57
58 // Allow left-shifting to happen on a wider type.
59 using RawWide = detail::max_int_for<Raw>;
60 return detail::shl_real<RawWide>(raw, -Fxd::frac_bits);
61
62 }
63 }
64
65
67 template<fixed_point Fxd>
68 requires detail::has_int_for<Fxd::int_bits, typename Fxd::raw_type>
69 [[nodiscard]]
70 constexpr
71 detail::select_int_for<Fxd::int_bits, typename Fxd::raw_type>
72 to_int(Fxd f)
73 noexcept
74 {
75 using I = detail::select_int_for<Fxd::int_bits, typename Fxd::raw_type>;
76 return to_int<I>(f);
77 }
78
79
80 template<int Int,
81 int Frac,
82 typename Raw>
83 template<std::integral I>
84 [[nodiscard]]
85 constexpr
87 const noexcept
88 {
89 return to_int<I>(*this);
90 }
91
92
94 template<std::floating_point Flt,
95 fixed_point Fxd>
96 constexpr
97 Flt
98 to_float(Fxd f)
99 noexcept
100 {
101 const auto r = f.raw_value;
102 const Flt fraw = detail::int_to_float<Flt>(r);
103 return std::ldexp(fraw, -Fxd::frac_bits);
104 }
105
106
108 template<fixed_point Fxd>
109 [[nodiscard]]
110 constexpr
111 typename std::numeric_limits<Fxd>::float_type
112 to_float(Fxd f)
113 noexcept
114 {
115 return to_float<typename std::numeric_limits<Fxd>::float_type>(f);
116 }
117
118
119 template<int Int,
120 int Frac,
121 typename Raw>
122 template<std::floating_point F>
123 [[nodiscard]]
124 constexpr
126 const noexcept
127 {
128 return to_float<F>(*this);
129 }
130
131
132 template<int Int, int Frac, typename Raw>
133 template<int Int2, int Frac2, typename Raw2>
134 [[nodiscard]]
135 constexpr
137 const noexcept
138 {
139 return fixed_cast<fixed<Int2, Frac2, Raw2>>(*this);
140 }
141
142}
143
144
145#endif
Concept to match any fxd::fixed
Definition: concepts.hpp:19
This is the namespace where the entire library is defined.
Definition: casting.hpp:19
constexpr I to_int(Fxd f) noexcept
Convert to integer.
Definition: conversions.hpp:45
constexpr Flt to_float(Fxd f) noexcept
Convert a fixed-point to a floating-point type, rounds to zero.
Definition: conversions.hpp:98
The fixed-point class template.
Definition: fixed.hpp:38