Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
numeric_limits.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "precision.hpp"
4#include <limits>
5#include <type_traits>
6
7namespace uni20
8{
9
16template <typename T> struct numeric_limits;
17
18template <typename T>
19 requires(std::is_arithmetic_v<T> && std::numeric_limits<T>::is_specialized)
21{
22 using std::numeric_limits<T>::epsilon;
23
25 static constexpr int digits() noexcept { return std::numeric_limits<T>::digits; }
26 static constexpr int digits(T const&) noexcept { return digits(); }
27 static constexpr int digits(Precision p)
28 {
30 return digits();
31 }
32
34 static constexpr int digits10() noexcept { return std::numeric_limits<T>::digits10; }
35 static constexpr int digits10(T const&) noexcept { return digits10(); }
36 static constexpr int digits10(Precision p)
37 {
39 return digits10();
40 }
41
43 static constexpr int max_digits10() noexcept { return std::numeric_limits<T>::max_digits10; }
44 static constexpr int max_digits10(T const&) noexcept { return max_digits10(); }
45 static constexpr int max_digits10(Precision p)
46 {
48 return max_digits10();
49 }
50
52 static constexpr T epsilon(Precision p)
53 {
55 return std::numeric_limits<T>::epsilon();
56 }
57
59 template <class U>
60 requires(std::is_same_v<T, U> && std::numeric_limits<T>::is_specialized)
61 static constexpr T epsilon(U const&) noexcept
62 {
63 return std::numeric_limits<T>::epsilon();
64 }
65
66 private:
67 static constexpr void require_precision(Precision p)
68 {
69 auto native = std::numeric_limits<T>::is_exact ? Precision::exact() : Precision::bits(digits());
70 if (p != native) throw std::invalid_argument("fixed-precision scalar requires its native precision");
71 }
72};
73
74template <typename T>
75 requires requires { numeric_limits<T>::is_specialized; }
76struct numeric_limits<T const> : numeric_limits<T>
77{};
78
79template <typename T>
80 requires requires { numeric_limits<T>::is_specialized; }
81struct numeric_limits<T volatile> : numeric_limits<T>
82{};
83
84template <typename T>
85 requires requires { numeric_limits<T>::is_specialized; }
86struct numeric_limits<T const volatile> : numeric_limits<T>
87{};
88
94template <typename T>
95inline constexpr bool has_numeric_limits_v =
96 requires { requires numeric_limits<std::remove_cvref_t<T>>::is_specialized; };
97
103template <class T>
104 requires(requires(T const& x) { x.is_exact(); } || has_numeric_limits_v<T>)
105constexpr bool is_exact(T const& x)
106{
107 if constexpr (requires { x.is_exact(); })
108 return x.is_exact();
109 else
111}
112
113} // namespace uni20
Exact arithmetic or an explicit binary working precision.
Definition core/precision.hpp:13
static constexpr Precision exact() noexcept
No approximation has been selected; rational arithmetic remains exact.
Definition core/precision.hpp:17
constexpr bool has_numeric_limits_v
True when Uni20 has numeric limits for T.
Definition numeric_limits.hpp:95
Definition qnum.hpp:403
Definition data_table.cpp:8
Definition async/async.hpp:26
constexpr bool is_exact(detail::standard_complex< T > const &x)
A standard complex value is exact only when both components are exact.
Definition math.hpp:50
mpreal epsilon(Precision precision)
Spacing above one for a specified binary working precision.
Definition mpreal.hpp:805
constexpr void require_precision(Precision p)
Reject an operation precision incompatible with a fixed scalar result.
Definition runtime_precision.hpp:66
static constexpr int max_digits10(Precision p)
Definition numeric_limits.hpp:45
static constexpr int digits10(T const &) noexcept
Definition numeric_limits.hpp:35
static constexpr int digits(Precision p)
Definition numeric_limits.hpp:27
static constexpr T epsilon(Precision p)
Spacing above one at this type's precision; reject incompatible requests.
Definition numeric_limits.hpp:52
static constexpr T epsilon(U const &) noexcept
Spacing above one, accepting an exemplar for scalar-generic code.
Definition numeric_limits.hpp:61
static constexpr int digits10() noexcept
Decimal digits preserved by conversion into this native type.
Definition numeric_limits.hpp:34
static constexpr int digits10(Precision p)
Definition numeric_limits.hpp:36
static constexpr int digits() noexcept
Fixed significand capacity, also available through an exemplar or precision.
Definition numeric_limits.hpp:25
static constexpr int digits(T const &) noexcept
Definition numeric_limits.hpp:26
static constexpr int max_digits10(T const &) noexcept
Definition numeric_limits.hpp:44
static constexpr int max_digits10() noexcept
Decimal digits sufficient to round-trip a value of this native type.
Definition numeric_limits.hpp:43
Project-level numeric limits customization point.
Definition numeric_limits.hpp:16