ATLAS Offline Software
Loading...
Searching...
No Matches
ap_fixed.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef GLOBALSIM_AP_FIXED_H
6#define GLOBALSIM_AP_FIXED_H
7
8#include <cstddef>
9#include <sstream>
10
11/*
12 * representation of a fixed point number.
13 * A fixed point number has a fixed width and precision.
14 * This implementation uses an C++ int type to store the bits.
15 * so allowing fast integer arithmetic.
16 */
17
18
19namespace GlobalSim {
20
21
22 struct Round{};
23 struct Trunc{};
24 struct XilDef{};
25
26 template<std::size_t width, typename T>
27 constexpr T max_to_overflow() {
28 T t{0};
29 static_assert(8*sizeof(t) >= width, "ap_fixed underlying int to small");
30 for (std::size_t i = 0; i <= sizeof(t)*8-width; ++i){
31 T bit{1};
32 t = t+(bit<<i);
33 }
34
35 t = t << (width-1);
36 return t;
37 }
38
39 template <std::size_t width,
40 std::size_t dp,
41 typename S=XilDef,
42 typename T=int16_t,
43 typename WS=int32_t>
44 struct ap_fixed {
45
46 T m_value = T{0};
48
49 bool m_ovflw{false};
50 friend std::ostream& operator<<(std::ostream& os,
52 os << ap.m_value << ' ' << double(ap);
53 return os;
54 }
55
56 ap_fixed() = default;
57
58 ap_fixed(const double d) requires(std::is_same_v<S, Round>):
59 m_value(d * double (1<< dp) + (d >= 0 ? 0.5 : -0.5)){
61 }
62
63 ap_fixed(const double d) requires(std::is_same_v<S, XilDef>):
64 m_value(d * double (1<< dp) + (d >= 0 ? 0. : -1.0)){
66 }
67
68
69 operator double() const{
70 return double(this->m_value) / double(1 << dp);
71 }
72
73
74 static ap_fixed form(T v) {
75 ap_fixed k; k.m_value = v; k.test_overflow();return k;
76 }
77
78 const ap_fixed operator + (const ap_fixed& f) const {
79 return form(this->m_value + f.m_value);
80 }
81
82
83 const ap_fixed& operator += (const ap_fixed& f) {
84 this->m_value += f.m_value;
86 return *this;
87 }
88
89 ap_fixed operator - (const ap_fixed& f) const {
90 return form(this->m_value - f.m_value);
91 }
92
93
94 const ap_fixed& operator -= (const ap_fixed& f) {
95 this->m_value -= f.m_value;
97 return *this;
98 }
99
100 ap_fixed operator * (const ap_fixed& f) const {
101 return form((WS(this->m_value) * WS(f.m_value)) >> dp);
102 }
103
104 const ap_fixed& operator *= (const ap_fixed& f) {
105 this->m_value = (WS(this->m_value) * WS(f.m_value) >> dp);
107 return *this;
108 }
109
110
111 ap_fixed operator / (const ap_fixed& f) const {
112 return form((WS(this->m_value) << dp) / WS(f.m_value));
113 }
114
115 const ap_fixed& operator /= (const ap_fixed& f) {
116 this->m_value = ((WS(this->m_value) << dp) / WS(f.m_value));
118 return *this;
119 }
120
121 // negation
123 return form(-this->m_value);
124 }
125
127
128 if (m_value > 0) {
129 if (m_value & m_overflow_mask) {
130 m_ovflw=true;
131 }
132 } else {
133 if (-m_value & m_overflow_mask) {
134 m_ovflw=true;
135 }
136 }
137
138 if (m_ovflw) {
139 std::stringstream ss;
140 T val = std::abs(m_value);
141
142 ss << "ap_fixed overflow. val: "
143 << m_value << " abs(val): " << val
144 << ' ' << std::hex << val
145 << " masked " << (val & m_overflow_mask);
146 throw std::out_of_range(ss.str());
147 }
148 }
149 };
150}
151
152#endif
static Double_t ss
const double width
AlgTool that to test whether expected the TIP values generated by data supplied by eEmMultTestBench c...
constexpr T max_to_overflow()
Definition ap_fixed.h:27
friend std::ostream & operator<<(std::ostream &os, const ap_fixed< width, dp, S, T, WS > ap)
Definition ap_fixed.h:50
static ap_fixed form(T v)
Definition ap_fixed.h:74
static constexpr int16_t m_overflow_mask
Definition ap_fixed.h:47
ap_fixed operator-() const
Definition ap_fixed.h:122
ap_fixed operator/(const ap_fixed &f) const
Definition ap_fixed.h:111
const ap_fixed & operator+=(const ap_fixed &f)
Definition ap_fixed.h:83
const ap_fixed & operator*=(const ap_fixed &f)
Definition ap_fixed.h:104
ap_fixed(const double d)
Definition ap_fixed.h:63
const ap_fixed & operator-=(const ap_fixed &f)
Definition ap_fixed.h:94
ap_fixed(const double d)
Definition ap_fixed.h:58
const ap_fixed operator+(const ap_fixed &f) const
Definition ap_fixed.h:78
ap_fixed operator*(const ap_fixed &f) const
Definition ap_fixed.h:100
const ap_fixed & operator/=(const ap_fixed &f)
Definition ap_fixed.h:115