GnuCash  4.12-73-g094a971c03+
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 extern "C"
29 {
30 #ifndef __STDC_LIMIT_MACROS
31 #define __STDC_LIMIT_MACROS 1
32 #endif
33 #ifndef __STDC_CONSTANT_MACROS
34 #define __STDC_CONSTANT_MACROS 1
35 #endif
36 #ifndef __STDC_FORMAT_MACROS
37 #define __STDC_FORMAT_MACROS 1
38 #endif
39 #include <inttypes.h>
40 }
41 
42 #include <stdexcept>
43 #include <string>
44 #include <ostream>
45 #include <type_traits>
46 
47 //using std::string;
64 class GncInt128
65 {
66  uint64_t m_hi;
67  uint64_t m_lo;
68 
69 public:
70  static const unsigned int flagbits = 3;
71  static const unsigned int numlegs = 2;
72  static const unsigned int legbits = 64;
73  static const unsigned int maxbits = legbits * numlegs - flagbits;
74 
75 enum // Values for m_flags
76 {
77  pos = 0,
78  neg = 1,
79  overflow = 2,
80  NaN = 4
81 };
92  GncInt128();
93  template <typename T>
94  GncInt128(T lower) : GncInt128(INT64_C(0), static_cast<int64_t>(lower))
95  {
96  static_assert (std::is_integral<T>(),
97  "GncInt128 can be constructed only with "
98  "integral arguments.");
99  }
100  GncInt128(uint64_t lower) : GncInt128 {UINT64_C(0), lower} {}
103  template <typename T, typename U>
104  GncInt128(T upper, U lower, unsigned char flags = '\0') :
105  GncInt128 {static_cast<int64_t>(upper),
106  static_cast<int64_t>(lower), flags}
107  {
108  static_assert (std::is_integral<T>(),
109  "GncInt128 can be constructed only with "
110  "integral arguments.");
111  static_assert (std::is_integral<U>(),
112  "GncInt128 can be constructed only with "
113  "integral arguments.");
114  }
115 
116  GncInt128 (int64_t upper, int64_t lower, unsigned char flags = '\0');
117  template <typename T>
118  GncInt128(T upper, uint64_t lower) :
119  GncInt128 {static_cast<int64_t>(upper), lower}
120  {
121  static_assert (std::is_integral<T>(),
122  "GncInt128 can be constructed only with "
123  "integral arguments.");
124  }
125 
126  GncInt128 (int64_t upper, uint64_t lower, unsigned char flags = '\0');
127  GncInt128 (uint64_t upper, uint64_t lower, unsigned char flags = '\0');
135  GncInt128& zero() noexcept;
136 
143  int cmp (const GncInt128& b) const noexcept;
144 
150  GncInt128 gcd (GncInt128 b) const noexcept;
156  GncInt128 lcm (const GncInt128& b) const noexcept;
157 
165  GncInt128 pow (unsigned int n) const noexcept;
166 
176  void div (const GncInt128& d, GncInt128& q, GncInt128& r) const noexcept;
177 
185  explicit operator int64_t() const;
193  explicit operator uint64_t() const;
194 
198  bool isNeg () const noexcept;
202  bool isBig () const noexcept;
207  bool isOverflow () const noexcept;
211  bool isNan () const noexcept;
215  bool isZero() const noexcept;
219  bool valid() const noexcept;
220 
224  unsigned int bits() const noexcept;
225 
234  char* asCharBufR(char* buf) const noexcept;
235 
236  GncInt128 abs() const noexcept;
237 
238  GncInt128 operator-() const noexcept;
239  explicit operator bool() const noexcept;
240 
241  GncInt128& operator++ () noexcept;
242  GncInt128& operator++ (int) noexcept;
243  GncInt128& operator-- () noexcept;
244  GncInt128& operator-- (int) noexcept;
245  GncInt128& operator<<= (unsigned int i) noexcept;
246  GncInt128& operator>>= (unsigned int i) noexcept;
247  GncInt128& operator+= (const GncInt128& b) noexcept;
248  GncInt128& operator-= (const GncInt128& b) noexcept;
249  GncInt128& operator*= (const GncInt128& b) noexcept;
250  GncInt128& operator/= (const GncInt128& b) noexcept;
251  GncInt128& operator%= (const GncInt128& b) noexcept;
252  GncInt128& operator&= (const GncInt128& b) noexcept;
253  GncInt128& operator|= (const GncInt128& b) noexcept;
254  GncInt128& operator^= (const GncInt128& b) noexcept;
255 
256 };
257 
258 static const GncInt128 k_gncint128_Max {UINT64_MAX, UINT64_MAX, GncInt128::pos};
259 static const GncInt128 k_gncint128_Min {UINT64_MAX, UINT64_MAX, GncInt128::neg};
260 
261 GncInt128 operator+ (GncInt128 a, const GncInt128& b) noexcept;
262 GncInt128 operator- (GncInt128 a, const GncInt128& b) noexcept;
263 GncInt128 operator* (GncInt128 a, const GncInt128& b) noexcept;
264 GncInt128 operator/ (GncInt128 a, const GncInt128& b) noexcept;
265 GncInt128 operator% (GncInt128 a, const GncInt128& b) noexcept;
266 GncInt128 operator& (GncInt128 a, const GncInt128& b) noexcept;
267 GncInt128 operator| (GncInt128 a, const GncInt128& b) noexcept;
268 GncInt128 operator^ (GncInt128 a, const GncInt128& b) noexcept;
269 GncInt128 operator<< (GncInt128 a, unsigned int b) noexcept;
270 GncInt128 operator>> (GncInt128 a, unsigned int b) noexcept;
271 
272 bool operator== (const GncInt128& a, const GncInt128& b) noexcept;
273 bool operator!= (const GncInt128& a, const GncInt128& b) noexcept;
274 bool operator<= (const GncInt128& a, const GncInt128& b) noexcept;
275 bool operator>= (const GncInt128& a, const GncInt128& b) noexcept;
276 bool operator< (const GncInt128& a, const GncInt128& b) noexcept;
277 bool operator> (const GncInt128& a, const GncInt128& b) noexcept;
278 
279 std::ostream& operator<< (std::ostream&, const GncInt128&) noexcept;
280 
283 GncInt128 gcd (int64_t a, int64_t b);
284 
287 GncInt128 lcm (int64_t a, int64_t b);
288 
289 #endif //GNCINT128_H
290 
char * asCharBufR(char *buf) const noexcept
Fills a supplied buffer with a representation of the number in base 10.
Definition: gnc-int128.cpp:922
bool isBig() const noexcept
Definition: gnc-int128.cpp:256
GncInt128 gcd(GncInt128 b) const noexcept
Computes the Greatest Common Divisor between the object and parameter.
Definition: gnc-int128.cpp:185
GncInt128 pow(unsigned int n) const noexcept
Computes the object raised to the parameter&#39;s power.
Definition: gnc-int128.cpp:232
bool valid() const noexcept
Definition: gnc-int128.cpp:274
GncInt128()
Default constructor.
Definition: gnc-int128.cpp:67
GncInt128(T upper, U lower, unsigned char flags='\0')
Double-integer constructor template.
Definition: gnc-int128.hpp:104
bool isNan() const noexcept
Definition: gnc-int128.cpp:268
bool isZero() const noexcept
Definition: gnc-int128.cpp:280
GncInt128 lcm(const GncInt128 &b) const noexcept
Computes the Least Common Multiple between the object and parameter.
Definition: gnc-int128.cpp:224
bool isNeg() const noexcept
Definition: gnc-int128.cpp:250
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:727
int cmp(const GncInt128 &b) const noexcept
Compare function.
Definition: gnc-int128.cpp:154
bool isOverflow() const noexcept
Definition: gnc-int128.cpp:262
GncInt128 & zero() noexcept
Clear the object.
Definition: gnc-int128.cpp:125
unsigned int bits() const noexcept
Definition: gnc-int128.cpp:296