GnuCash  5.6-150-g038405b370+
gnc-int128.hpp
1 /********************************************************************
2  * qofmath128.h -- an 128-bit integer library *
3  * Copyright (C) 2004 Linas Vepstas <linas@linas.org> *
4  * Copyright (C) 2014 John Ralls <jralls@ceridwen.us> *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA gnu@gnu.org *
22  * *
23  *******************************************************************/
24 
25 #ifndef GNCINT128_H
26 #define GNCINT128_H
27 
28 #ifndef __STDC_LIMIT_MACROS
29 #define __STDC_LIMIT_MACROS 1
30 #endif
31 #ifndef __STDC_CONSTANT_MACROS
32 #define __STDC_CONSTANT_MACROS 1
33 #endif
34 #ifndef __STDC_FORMAT_MACROS
35 #define __STDC_FORMAT_MACROS 1
36 #endif
37 #include <inttypes.h>
38 
39 #include <stdexcept>
40 #include <string>
41 #include <ostream>
42 #include <type_traits>
43 
44 //using std::string;
61 class GncInt128
62 {
63  uint64_t m_hi;
64  uint64_t m_lo;
65 
66 public:
67  static const unsigned int flagbits = 3;
68  static const unsigned int numlegs = 2;
69  static const unsigned int legbits = 64;
70  static const unsigned int maxbits = legbits * numlegs - flagbits;
71 
72 enum // Values for m_flags
73 {
74  pos = 0,
75  neg = 1,
76  overflow = 2,
77  NaN = 4
78 };
89  GncInt128();
90  template <typename T,
91  std::enable_if_t<std::is_integral<T>::value, bool> = true>
92  GncInt128(T lower) : GncInt128(INT64_C(0), static_cast<int64_t>(lower))
93  {}
94  GncInt128(uint64_t lower) : GncInt128 {UINT64_C(0), lower} {}
97  template <typename T, typename U,
98  std::enable_if_t<(std::is_integral<T>::value &&
99  std::is_integral<U>::value), bool> = true>
100  GncInt128(T upper, U lower, unsigned char flags = '\0') :
101  GncInt128 {static_cast<int64_t>(upper),
102  static_cast<int64_t>(lower), flags} {}
103 
104  GncInt128 (int64_t upper, int64_t lower, unsigned char flags = '\0');
105  template <typename T,
106  std::enable_if_t<std::is_integral<T>::value, bool> = true>
107  GncInt128(T upper, uint64_t lower) :
108  GncInt128 {static_cast<int64_t>(upper), lower} {}
109 
110  GncInt128 (int64_t upper, uint64_t lower, unsigned char flags = '\0');
111  GncInt128 (uint64_t upper, uint64_t lower, unsigned char flags = '\0');
119  GncInt128& zero() noexcept;
120 
127  int cmp (const GncInt128& b) const noexcept;
128 
134  GncInt128 gcd (GncInt128 b) const noexcept;
140  GncInt128 lcm (const GncInt128& b) const noexcept;
141 
149  GncInt128 pow (unsigned int n) const noexcept;
150 
160  void div (const GncInt128& d, GncInt128& q, GncInt128& r) const noexcept;
161 
169  explicit operator int64_t() const;
177  explicit operator uint64_t() const;
178 
182  bool isNeg () const noexcept;
186  bool isBig () const noexcept;
191  bool isOverflow () const noexcept;
195  bool isNan () const noexcept;
199  bool isZero() const noexcept;
203  bool valid() const noexcept;
204 
208  unsigned int bits() const noexcept;
209 
218  char* asCharBufR(char* buf, uint32_t size) const noexcept;
219 
220  GncInt128 abs() const noexcept;
221 
222  GncInt128 operator-() const noexcept;
223  explicit operator bool() const noexcept;
224 
225  GncInt128& operator++ () noexcept;
226  GncInt128& operator++ (int) noexcept;
227  GncInt128& operator-- () noexcept;
228  GncInt128& operator-- (int) noexcept;
229  GncInt128& operator<<= (unsigned int i) noexcept;
230  GncInt128& operator>>= (unsigned int i) noexcept;
231  GncInt128& operator+= (const GncInt128& b) noexcept;
232  GncInt128& operator-= (const GncInt128& b) noexcept;
233  GncInt128& operator*= (const GncInt128& b) noexcept;
234  GncInt128& operator/= (const GncInt128& b) noexcept;
235  GncInt128& operator%= (const GncInt128& b) noexcept;
236  GncInt128& operator&= (const GncInt128& b) noexcept;
237  GncInt128& operator|= (const GncInt128& b) noexcept;
238  GncInt128& operator^= (const GncInt128& b) noexcept;
239 
240 };
241 
242 static const GncInt128 k_gncint128_Max {UINT64_MAX, UINT64_MAX, GncInt128::pos};
243 static const GncInt128 k_gncint128_Min {UINT64_MAX, UINT64_MAX, GncInt128::neg};
244 
245 GncInt128 operator+ (GncInt128 a, const GncInt128& b) noexcept;
246 GncInt128 operator- (GncInt128 a, const GncInt128& b) noexcept;
247 GncInt128 operator* (GncInt128 a, const GncInt128& b) noexcept;
248 GncInt128 operator/ (GncInt128 a, const GncInt128& b) noexcept;
249 GncInt128 operator% (GncInt128 a, const GncInt128& b) noexcept;
250 GncInt128 operator& (GncInt128 a, const GncInt128& b) noexcept;
251 GncInt128 operator| (GncInt128 a, const GncInt128& b) noexcept;
252 GncInt128 operator^ (GncInt128 a, const GncInt128& b) noexcept;
253 GncInt128 operator<< (GncInt128 a, unsigned int b) noexcept;
254 GncInt128 operator>> (GncInt128 a, unsigned int b) noexcept;
255 
256 bool operator== (const GncInt128& a, const GncInt128& b) noexcept;
257 bool operator!= (const GncInt128& a, const GncInt128& b) noexcept;
258 bool operator<= (const GncInt128& a, const GncInt128& b) noexcept;
259 bool operator>= (const GncInt128& a, const GncInt128& b) noexcept;
260 bool operator< (const GncInt128& a, const GncInt128& b) noexcept;
261 bool operator> (const GncInt128& a, const GncInt128& b) noexcept;
262 
263 std::ostream& operator<< (std::ostream&, const GncInt128&) noexcept;
264 
267 GncInt128 gcd (int64_t a, int64_t b);
268 
271 GncInt128 lcm (int64_t a, int64_t b);
272 
273 #endif //GNCINT128_H
274 
bool isBig() const noexcept
Definition: gnc-int128.cpp:253
GncInt128 gcd(GncInt128 b) const noexcept
Computes the Greatest Common Divisor between the object and parameter.
Definition: gnc-int128.cpp:182
GncInt128 pow(unsigned int n) const noexcept
Computes the object raised to the parameter&#39;s power.
Definition: gnc-int128.cpp:229
bool valid() const noexcept
Definition: gnc-int128.cpp:271
GncInt128()
Default constructor.
Definition: gnc-int128.cpp:64
bool isNan() const noexcept
Definition: gnc-int128.cpp:265
char * asCharBufR(char *buf, uint32_t size) const noexcept
Fills a supplied buffer with a representation of the number in base 10.
Definition: gnc-int128.cpp:918
bool isZero() const noexcept
Definition: gnc-int128.cpp:277
GncInt128 lcm(const GncInt128 &b) const noexcept
Computes the Least Common Multiple between the object and parameter.
Definition: gnc-int128.cpp:221
bool isNeg() const noexcept
Definition: gnc-int128.cpp:247
GncInt128(T upper, U lower, unsigned char flags='\0')
Double-integer constructor template.
Definition: gnc-int128.hpp:100
void div(const GncInt128 &d, GncInt128 &q, GncInt128 &r) const noexcept
Computes a quotient and a remainder, passed as reference parameters.
Definition: gnc-int128.cpp:723
int cmp(const GncInt128 &b) const noexcept
Compare function.
Definition: gnc-int128.cpp:151
bool isOverflow() const noexcept
Definition: gnc-int128.cpp:259
GncInt128 & zero() noexcept
Clear the object.
Definition: gnc-int128.cpp:122
unsigned int bits() const noexcept
Definition: gnc-int128.cpp:293